最近我們在做利用lstm網路對腦電波訊號(紡錘體)進行分類的相關工作。我們的資料集是來自於美國開源的睡眠資料集(national sleep research resource)
我們獲得資料報含 紡錘波的持續時間,振幅,時間,等幾個特徵。我們採集的樣本主要來自於正常人和病人。我們初步的思想是將紡錘波視為乙個事件,生成乙個序列。出現紡錘波訊號的為1,反之為0.然後利用神經網路,來學習這個序列的內部特徵,通過序列來判斷病人有沒有患病。
眾所周知lstm神經網路在處理時序資訊時有乙個很好的效果,特別是幾年來nlp的飛速發展。
我們首先需要的是對序列進行二進位制編碼
def bit_coding(data, step): #對乙個資料進行編碼
code =
pre_data = 0
count = 0
length = len(data)
while count < length:
n = (data[count]-pre_data) / step
if n > 0:
if n % 1 > 0:
n = int(n)
code += [0] * n + [1]
else:
n = int(n)
code += [0] * (n - 1) + [1]
pre_data = data[count]
count += 1
return code
其中的step就是設定的精度,多少步長進行統計,這個值將決定你獲得乙個腦電波的序列的維度大小。
我們再生成乙個腦電波的類的相關資訊
class spindledata:
path = ""
paths =
labels =
data =
step = 0.0001
max_length = 0#設定預設的編碼間隔
coding_q =
def __init__(self, path="datasets", step=0.0001 ):
self.path = path
self.step =step
self.paths, self.labels = self.get_data_labels() #獲得路徑以及標籤
self.coding()
def get_data_labels(self): # 返回獲取的資料以及標籤[0,1,0,1,...] "./datasets/"
path = self.path
cate = [(os.path.join(path, x)) for x in os.listdir(path)]
paths =
labels =
for i, p in enumerate(cate):
path_tmps = glob.glob(os.path.join(p, "*.csv"))
for p in path_tmps:
np.asarray(labels) #將標籤轉化為np的格式
return paths, labels
def coding(self):#所有的資料讀取以及儲存(這裡儲存了資料的原始資料占用記憶體可能比較大)
codeing_q =
for p in self.paths:
data = pd.read_csv(p, skiprows=(0, 1), sep=",")
print("正在讀取第%d個csv檔案..." % (self.paths.index(p)+1))
data =data['time_of_night']
for i, d in enumerate(self.data):
code = bit_coding(d, step=self.step)
print("正在對第%d個序列進行編碼..."%(i+1))
self.max_length = max([len(x) for x in codeing_q])
codeing_q = preprocessing.sequence.pad_sequences(codeing_q, maxlen=self.max_length) #將所有的串都弄成相同的維度
self.coding_q = np.asarray(codeing_q)
這個類主要包含編碼後的0/1序列,1序列表示的是紡錘波出現,0表示的是紡錘波沒有出現。同時我們利用了keras 的對齊。超過固定長度的部分會被截斷,不足的部分會補零。同時我們再生成乙個labels陣列,這個對應的是病人患病與健康。其實就是乙個二分類問題。
我們再來搭建乙個lstm神經網路
def learning_lstm(): #lstm暫時還是比較適合於文字中,對於有序序暫不合適
x_train, y_labels, length = data_test()
x_train = np.expand_dims(x_train, axis=2)
model = sequential()
# model.add(embedding(max_feature, 32))
model.add(lstm(32, input_shape=(length, 1)))
model.add(dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
model.summary()
history = model.fit(x_train, y_labels, epochs=10, batch_size=16, validation_split=0.2)
draw(history)
def data_test():
length = 0 #每乙個系列的長度
spindle = spindledata()
x_train = spindle.coding_q
y_train = spindle.labels
length = spindle.max_length
return x_train, y_train, length
我實驗中的step設定的最小間距0.0001,因此每個序列都有120,000維.暫時實驗的效果不是很明顯。
由於我們暫時獲取的資料還比較小,導致訓練不充分,同時可能會導致過擬合等問題。接下來我們會進行改進測試。
我先把github原始碼發上來,相關的原發發布到了我的github上: 歡迎指正!
腦電溯源定位
頭皮記錄的腦電是大腦中很多源在記錄點疊加起來的結果,而且,這些源的方向 一般隨著皮層的褶皺而變化 對最後測量出來的頭皮腦電有很大影響。所以不能簡單的把頭皮對應的啟用位置對映到皮層上去,那就只有借助於溯源方法了。所謂腦電溯源定位,也即腦電逆向問題,概括的說就是 根據頭表測量電位訊號,反演估計腦內神經活...
腦電電極帽
本文首發在個人部落格上 7988888.xyz 好了,上面說的這些是我最近遇到的問題,進入到今天分享的主題吧,今天要談到的是我們目前所使用到的電極帽種類,總體來說一共分為兩個大的種類 溼電極帽和幹電極帽 電極帽在eeg資料實驗中重要嗎?重要的,電極帽上一般都帶有電極感測器,通過在電極感測器與頭皮之間...
pytorch 對小鼠的腦電資料進行睡眠狀態三分類
3.分類結果 本文採用pytorch框架,用實驗室採集到老鼠大腦資料來學習一波多分類。我的資料是26只老鼠的mat形式的腦電資料,每個老鼠有15個通道,每個老鼠在不同的睡眠狀態擷取30段資料,每一段資料長為10s。這裡採集的睡眠狀態有三種,分別是awake,rem,和sws 這裡為了更好的獲取時域和...