请教一下,肌电的手势分类的应该用啥 CNN 模型?

2022-04-10 19:31:10 +08:00
 ALLROBOT

我不知道用什么 CNN 分类器能很好预测值

16 个电极模拟的值,每列代表某个电极在人体表面读取的生物信号强度数值,等数据缩放完了,数据格式大概如下:

[[-0.00001221  0.00001285  0.00000142 -0.00000145  0.00000089  0.00000128
  -0.00000432 -0.0000021  -0.00001083 -0.00000186 -0.000001   -0.00000192
   0.00000232  0.00000245 -0.00000036  0.00000399]
 [-0.00001103  0.00001196 -0.00000081 -0.00000296  0.00000162  0.00000013
  -0.00000231 -0.0000021  -0.00000726 -0.00000127  0.00000254 -0.00000042
   0.00000163  0.00000758 -0.00000008  0.00000972]
   ...
   ]

若使用 PIL 的 Image.fromarray(200 条 16 列的数值矩阵),输出为:

假若手打出 6 的手势,那么 16 个电极的一些电极贴近弯曲 3 个手指向后的手臂肌肉层能读取比较大的数值

可是,我用以下的代码训练几百轮,结果预测效果不太好,好几次预测,总是把实际值为 1 的手势预测输出 6

    def CNN(input_shape=(100,16,1), classes=9):
        X_input = Input(input_shape)

        X = Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='tanh', name='conv1')(
            X_input)
        X = MaxPooling2D(pool_size=(10, 1), strides=(10, 1), name='pool1')(X)

        X = Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='tanh', name='conv2')(X)
        X = MaxPooling2D(pool_size=(2, 1), strides=(2, 1), name='pool2')(X)

        X = Conv2D(filters=128, kernel_size=(3, 1), strides=(1, 1), padding='same', activation='tanh', name='conv3')(X)
        X = MaxPooling2D(pool_size=(2, 1), strides=(2, 1), name='pool3')(X)

        X = Flatten(name='flatten')(X)
        X = Dropout(0.5)(X)
        X = Dense(64, activation='tanh', name='fc1')(X)
        X = Dropout(0.4)(X)
        X = Dense(64, activation='tanh', name='fc2')(X)
        X = Dropout(0.3)(X)
        X = Dense(classes, activation='softmax')(X)

        model = Model(inputs=X_input, outputs=X, name='MultipleCNN')
        return model
        
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=500, batch_size=64, verbose=1,validation_data=(X_test, Y_test), callbacks=callbacks_list)

输出

......
Epoch 00999: val_accuracy did not improve from 0.82502
Epoch 1000/1000
138/138 [==============================] - 1s 8ms/step - loss: 0.0639 - accuracy: 0.9790 - val_loss: 1.0930 - val_accuracy: 0.8060

Epoch 01000: val_accuracy did not improve from 0.82502
276/276 [==============================] - 1s 3ms/step - loss: 0.0034 - accuracy: 0.9990
Train Loss = 0.003447444410994649
Train Accuracy = 0.9989800453186035
69/69 [==============================] - 0s 3ms/step - loss: 1.0930 - accuracy: 0.8060
Test Loss = 1.0929756164550781
Test Accuracy = 0.8059836626052856
time: 1228.2580664157867

我迷糊了,测试集有 80%准确率,我实际测了十几下,怎么都是预测错的😂

兄弟萌,这种数据应该用啥模型的比较好?

1748 次点击
所在节点    程序员
23 条回复
Cortez
2022-04-10 22:41:20 +08:00
@ALLROBOT 我怎么理解的是这个跟时间没关系啊,为什么用时间窗呢?如果每行 16 列是一个数据,各列的顺序又是固定的,哪怕是传感器几百次采样频率中的一次,那也就是一个姿势你可以采集很多组几乎相同的样本,这时候只要后期处理数据时注意 balance 就可以了。等训练好后,每次读出一组 16 列数据就可以进行一次分类。
ALLROBOT
2022-04-10 23:05:51 +08:00
@Cortez #21 不用时间窗的话,错误率比较高,我无法确保一帧能传达准确的信息(技术有限,我做不到一帧能预测准确)

和语音识别有点类似,分析语音信号的连续几十帧分别对应什么值,语音识别只分析一帧的话....
Cortez
2022-04-10 23:27:58 +08:00
@ALLROBOT 那如果用时间窗口的话也应该是在每行之内进行卷积,跨行咋解释?
语音识别和这个不一样,语音是和时间相关的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/846113

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX