はじめに
前回の計測では筋電位センサでじゃんけんの時の筋電位を計測しました.
今回は計測した筋電位から手の姿勢を推定できるか,chainerを使って検証してみます.
今回は計測した筋電位から手の姿勢を推定できるか,chainerを使って検証してみます.
筋肉の電気信号・筋電位の計測 - IMACEL Academy -人工知能・画像解析の技術応用に向けて-|LPixel(エルピクセル)
じゃんけんの姿勢を筋電位で計測して,識別できるか検証します
筋電図の特徴量
こちらの論文では8つの手動作姿勢の識別にどの特徴量を用いるのが良いか検証しています.
https://www.jstage.jst.go.jp/article/kikaic/79/808/79_4746/_pdf
検証している特徴量は以下の通りです.
1.生データ
2.積分筋電位(IEMG)
3.最大成分周波数(FFT Peek)
4.パワースペクトル
5.立ち上がり筋電位
6.ウェーブレット係数
SVMを用いて識別をしていますが,IEMGを特徴量として用いた時が最も高い識別率を示しています.
この記事ではパワースペクトルを特徴量として識別してみます.
https://www.jstage.jst.go.jp/article/kikaic/79/808/79_4746/_pdf
検証している特徴量は以下の通りです.
1.生データ
2.積分筋電位(IEMG)
3.最大成分周波数(FFT Peek)
4.パワースペクトル
5.立ち上がり筋電位
6.ウェーブレット係数
SVMを用いて識別をしていますが,IEMGを特徴量として用いた時が最も高い識別率を示しています.
この記事ではパワースペクトルを特徴量として識別してみます.
データセットの作成
計測条件と計測箇所は前回と同様です.
FFTの条件
・サンプリング数 256
・オーバーラップ数 64
・窓関数 ハミング窓
3つのセンサのパワースペクトルから成るベクトルと姿勢ラベルを1セットとすると合計で225セット.
データセットの作成のコーディングに手間を取ったのでプログラムを載せておきます.
FFTの条件
・サンプリング数 256
・オーバーラップ数 64
・窓関数 ハミング窓
3つのセンサのパワースペクトルから成るベクトルと姿勢ラベルを1セットとすると合計で225セット.
データセットの作成のコーディングに手間を取ったのでプログラムを載せておきます.
# データセット 学習データ(パワースペクトル)*センサ数+ラベル(姿勢) emg_dataset = np.empty((SAMPLING_N // 2 + 1) * SENSOR_NUM + 1) for posture in range(POSTURE_NUM): pyplot.figure() data_csv = pd.read_csv("emg" + str(posture) + ".csv", header=None) # 時刻ごとのFFT index = 0 while index + SAMPLING_N < data_csv.shape[0]: amp_array = np.empty(0) # センサごとのFFT for i in range(SENSOR_NUM): emg = data_csv[i].values[index: index + SAMPLING_N] # フィルター処理 emg = signal.detrend(emg) emg = np.convolve(emg, np.ones(10) / 10.0, mode='same') # 窓関数 window = np.hamming(SAMPLING_N) f = np.fft.fft(emg * window) amp = np.abs(f) amp = amp[0: SAMPLING_N // 2 + 1] amp_array = np.append(amp_array, amp) # ラベルとして姿勢を登録 label = posture amp_array = np.append(amp_array, label) emg_dataset = np.vstack((emg_dataset, amp_array)) index += SAMPLING_N // 4 emg_dataset = np.delete(emg_dataset, 0, 0) # 配列並び替え np.random.shuffle(emg_dataset) train_data = emg_dataset[:, 0: emg_dataset.shape[1] - 1].astype(dtype=np.float32) label_data = emg_dataset[:, emg_dataset.shape[1] - 1: emg_dataset.shape[1]].T.astype(dtype=np.int32) label_data = label_data[0] # 学習データの教師データとテスト用データに分ける threshold = np.int32(emg_dataset.shape[0] * 9 / 10) train = tuple_dataset.TupleDataset(train_data[0:threshold], label_data[0:threshold]) test = tuple_dataset.TupleDataset(train_data[threshold:], label_data[threshold:])
一次元ベクトルのデータセット.py
訓練データとラベルは別に扱いますが,データをランダムに扱うために
まずは学習データの最後にラベルを追加して,シャッフルし,その後分離しています.
まずは学習データの最後にラベルを追加して,シャッフルし,その後分離しています.
ニューラルネットワークの作成
使用したニューラルネットワークは以下の通り.
入力層 129x3次元
中間層 512
出力層 3次元
重み決定法 確率的勾配法
学習回数 200
入力層 129x3次元
中間層 512
出力層 3次元
重み決定法 確率的勾配法
学習回数 200
結果!
学習するに連れて学習データ,テストデータ共に誤差が小さくなっていることが確認できます.
ちなみに識別率は100%を達成しました.
ちなみに識別率は100%を達成しました.