プログラム開発備忘録

プログラム開発備忘録

プログラム開発中に詰まった箇所を備忘録として記録します。

【Python】多変量時系列データ畳み込みニューラルネットワーク、データ前処理部分の変更

問題点:畳み込みニューラルネットワーク学習モデルの精度が低い

解決方法:データの前処理部分のコードを変更

詳細
被験者の運動動作時の脳波データ(データセット:BCI competition IV dataset2a)から、動かそうとした箇所(舌,右手,左手,両足の4パターン)を判定するプログラムの作成中、参考にしたプログラム(https://github.com/ahujak/EEG_BCI)との正解率と異常に離れていることに気づいた。学習モデルは同じものを生成していたので、データを読み込む部分がおかしいと睨み、コードの修正を行った。

開発環境:GoogleColaboratory

参考にしたプロジェクトはデータセットが入っていなかったので、データを読み込む部分は別の方のコードを参考に作成していた。参照するディレクトリは"./gdrive/MyDrive/data/A01T_slice.mat"(A01~A09)となっている。


修正前のコード

import h5py
import numpy as np

#ファイルの読み込み
def import_data(every=False):
    if every:
        electrodes = 25
    else:
        electrodes = 22
    X, y = [], []
    drive_root_dir="./gdrive/My Drive/data"
    for i in range(9):
        A01T = h5py.File(drive_root_dir + "/A0" + str(i + 1) + 'T_slice.mat', 'r')
        X1 = np.copy(A01T['image'])
        X.append(X1[:, :electrodes, :])
        y1 = np.copy(A01T['type'])
        y1 = y1[0, 0:X1.shape[0]:1]
        y.append(np.asarray(y1, dtype=np.int32))

    for subject in range(9):
        delete_list = []
        for trial in range(288):
            if np.isnan(X[subject][trial, :, :]).sum() > 0:
                delete_list.append(trial)
        X[subject] = np.delete(X[subject], delete_list, 0)
        y[subject] = np.delete(y[subject], delete_list)
    y = [y[i] - np.min(y[i]) for i in range(len(y))]
    return X, y

#データの変換
def train_test_subject(X, y, train_all=True, standardize=True):

    l = np.random.permutation(len(X[0]))
    X_test = X[0][l[:100], :, :]
    y_test = y[0][l[:100]]

    if train_all:
        X_train = np.concatenate((X[0][l[100:], :, :], X[1], X[2], X[3], X[4], X[5], X[6], X[7], X[8]))
        y_train = np.concatenate((y[0][l[100:]], y[1], y[2], y[3], y[4], y[5], y[6], y[7], y[8]))

    else:
        X_train = X[0][l[100:], :, :]
        y_train = y[0][l[100:]]

    X_train_mean = X_train.mean(0)
    X_train_var = np.sqrt(X_train.var(0))

    if standardize:
        X_train -= X_train_mean
        X_train /= X_train_var
        X_test -= X_train_mean
        X_test /= X_train_var

    X_train = np.transpose(X_train, (0, 2, 1))
    X_test = np.transpose(X_test, (0, 2, 1))

    return X_train, X_test, y_train, y_test

X, y = import_data(every=False)
X_train,X_test,y_train,y_test = train_test_subject(X, y)


修正後のコード

import h5py
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
import numpy as np

drive_root_dir = './gdrive/My Drive/data'
def load_data_from(file_num):
	file_name = drive_root_dir + '/A0' + str(file_num) + 'T_slice.mat'
	cur_data = h5py.File(file_name, 'r')
	X = np.copy(cur_data['image'])[:, 0:22, :]
	y = np.copy(cur_data['type'])[0,0:X.shape[0]:1]
	y = np.asarray(y)
	# print(X.shape)
	# print(y.shape)

	return X,y

X, y = load_data_from(1)
X = np.nan_to_num(X)
y = LabelEncoder().fit_transform(y)
y = OneHotEncoder(sparse=False).fit_transform(y.reshape(-1, 1))
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 100)
for i in range(2,10):
    X2, y2 = load_data_from(i)
    X2 = np.nan_to_num(X2)
    y2 = LabelEncoder().fit_transform(y2)
    y2 = OneHotEncoder(sparse = False).fit_transform( y2.reshape(-1,1) )
    X2_train, X2_test, y2_train, y2_test = train_test_split(X, y, test_size=50)
    X_train = np.concatenate((X_train,X2),axis=0)
    X_test = np.concatenate((X_test, X2_test), axis=0)
    y_train = np.concatenate((y_train, y2), axis=0)
    y_test = np.concatenate((y_test, y2_test), axis=0)


締め
これにより、学習モデルの正解率は57%から72%になった。
やはりデータの前処理部分に問題があったみたいだが、未だに修正前のコードの悪点が分かっていないので、コメントしていただけると嬉しいです。


参考にしたコード
学習モデル:https://github.com/ahujak/EEG_BCI
修正後のコード:https://github.com/ritabugking/ECE239AS-DeepLearning/blob/master/finalProject/cnn1.py