【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