请教一下,肌电的手势分类的应该用啥 CNN 模型? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
ALLROBOT
V2EX    程序员

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

  •  
  •   ALLROBOT 2022-04-10 19:31:10 +08:00 2045 次点击
    这是一个创建于 1279 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我不知道用什么 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 列的数值矩阵),输出为: image9a8ecb040d8e6004.png

    假若手打出 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%准确率,我实际测了十几下,怎么都是预测错的

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

    第 1 条附言    2022-04-10 21:11:08 +08:00
    顺便求指教,更改模型结构需要什么诀窍,才能使识别精度上来呢
    第 2 条附言    2022-04-10 22:43:48 +08:00
    CNN 预测不准的问题解决了,是我的提取数据的一个步骤出错了
    23 条回复    2022-04-10 23:27:58 +08:00
    airqj
        1
    airqj  
       2022-04-10 19:48:38 +08:00
    从 vgg 枚举到最新模型不就知道了 :)
    ALLROBOT
        2
    ALLROBOT  
    OP
       2022-04-10 20:23:37 +08:00
    @airqj #1 VGG 枚举到最新模型?原谅我,我是深度学习野路子的,你说的 VGG 怎么枚举到最新模型我真不知道

    (网上有 VGG 模型,我姑且试试看吧)
    ALLROBOT
        3
    ALLROBOT  
    OP
       2022-04-10 20:59:25 +08:00
    问了导师结果被喷了,说我 CNN 模型和别人的太重复了,写不出来新什么东西

    我问能用 VGG 模型,导师一顿狂喷为啥非要用别人的模型,你就不能改一改网络结构吗,至少把精度提高到 90%

    @airqj #1 能指教一下怎么改模型吗

    虽然自学了吴恩达、周志华的课程,对于这些模型结构我比较陌生,有什么改模型的诀窍吗,求指路
    jdhao
        4
    jdhao  
       2022-04-10 21:07:06 +08:00 via Android
    vgg 肯定不行,都是处理二维图像的,你的数据是一维的,别听不懂的人在那瞎扯淡。

    大概率你需要自己试试不同的模型,或者特征上下点功夫,对特征做一些特征工程变换?
    ALLROBOT
        5
    ALLROBOT  
    OP
       2022-04-10 21:08:42 +08:00
    @jdhao #4 VGG 应该可以的,因为我把肌电数据处理成二维图像,再输入到模型中
    ALLROBOT
        6
    ALLROBOT  
    OP
       2022-04-10 21:10:08 +08:00
    导师带过几个涉及深度学习的项目
    @jdhao #4
    jdhao
        7
    jdhao  
       2022-04-10 21:14:59 +08:00 via Android
    @ALLROBOT 你这数据就 16 维,你怎么转图像? vgg 输入都是 224*224*3 的图像
    ALLROBOT
        8
    ALLROBOT  
    OP
       2022-04-10 21:18:51 +08:00 via Android
    @jdhao 以时间窗滑动,每个时间窗内的 16 列数据处理成( 100 ,16 ,1 )
    Cortez
        9
    Cortez  
       2022-04-10 21:33:38 +08:00
    @ALLROBOT 不是 1 行 16 列的信号对应一个动作嘛?
    Calibans
        10
    Calibans  
       2022-04-10 21:38:40 +08:00 via iPhone
    试试 lstm 或者 transformer
    nightwitch
        11
    nightwith  
       2022-04-10 21:44:38 +08:00
    刚好做过类似的,只是我是在骨架的数据上做的。 在测试集上准确度和现实场景中的准确度会差很多,因为在现实场景下做手势动作的情况太多变了,数据集覆盖不了真实情况。真实的数据流是没有明确的起始和结束的,数据会和你数据集里切好段的差很多。

    你把在测试集上的准确度提上来以后,在真实场景下用还要调很久,不是简单套个模型就 ok 的
    airqj
        12
    airqj  
       2022-04-10 21:55:53 +08:00
    @jdhao 大把模型把一维数据转成二维数据然后用 cnn 来识别,比如有的语音识别就先把语音信号来个 fft 处理再输入 cnn
    @ALLROBOT 怪我没审好题。你这数据才 16 维,感觉都用不到 cnn,xgboost 大法试试
    ALLROBOT
        13
    ALLROBOT  
    OP
       2022-04-10 21:56:34 +08:00 via Android
    @Cortez 各个电极的值加起来除以电极的个数得到均值,如果高于休息状态的均值视为活动段,此时时间窗开始滑动

    @Calibans 好的,我正想用几个模型看看呢


    @nightwitch 真实场景一般怎么调的正好提高精度哈?

    我不是手动打标签的,给肌电设了阈值,某个电极的高于阈值可以视为活动段开始,低于的视为结束

    关于数据集,我尽可能覆盖面广一点,不同动作或力度的同一手势都收集看看
    ALLROBOT
        14
    ALLROBOT  
    OP
       2022-04-10 21:57:55 +08:00 via Android
    @airqj 网上的数据集是 16 列的,现实的传感器仅有 6 个(#-.-)
    ttgo
        15
    ttgo  
       2022-04-10 21:58:54 +08:00
    在一个展会上学生区里见过个类似的,512 还是 128 来着长度的信号识别手势,人家就用了两个 fc 。。
    ALLROBOT
        16
    ALLROBOT  
    OP
       2022-04-10 21:59:45 +08:00 via Android
    @Cortez 再补充一下,每行 16 列是传感器几百次采样频率中的一次
    airqj
        17
    airqj  
       2022-04-10 22:05:34 +08:00
    @ALLROBOT 说不定回归模型还靠谱一些
    Gezqh
        18
    Gezqh  
       2022-04-10 22:1:27 +08:00
    是时间序列的数据么?可以找一些专门用来对多维时间序列进行分类的模型吧?
    Gezqh
        19
    Gezqh  
       2022-04-10 22:12:07 +08:00
    或者是将时间序列数据转换成梅尔频谱试试(时域到频域)?
    ALLROBOT
        20
    ALLROBOT  
    OP
       2022-04-10 22:39:16 +08:00
    @ttgo #15 很惭愧,我比不上人家调的优秀

    @Gezqh #18 大概不是?时间序列是随着时间流动收集数据的,模型按不同时间预测数据可能对应的状态,而肌电活动段按时间窗口分割的,单单提取一个时间窗口不分时间前后,模型只对一个时间窗内的不同电极的生物信号强度,负责对比各列的数值大小从而预测对应的状态,预测状态和上一个或下一个时间窗口关系不大(如果时间窗口包括休息状态的肌电,预测容易出错)
    Cortez
        21
    Cortez  
       2022-04-10 22:41:20 +08:00
    @ALLROBOT 我怎么理解的是这个跟时间没关系啊,为什么用时间窗呢?如果每行 16 列是一个数据,各列的顺序又是固定的,哪怕是传感器几百次采样频率中的一次,那也就是一个姿势你可以采集很多组几乎相同的样本,这时候只要后期处理数据时注意 balance 就可以了。等训练好后,每次读出一组 16 列数据就可以进行一次分类。
    ALLROBOT
        22
    ALLROBOT  
    OP
       2022-04-10 23:05:51 +08:00
    @Cortez #21 不用时间窗的话,错误率比较高,我无法确保一帧能传达准确的信息(技术有限,我做不到一帧能预测准确)

    和语音识别有点类似,分析语音信号的连续几十帧分别对应什么值,语音识别只分析一帧的话....
    Cortez
        23
    Cortez  
       2022-04-10 23:27:58 +08:00
    @ALLROBOT 那如果用时间窗口的话也应该是在每行之内进行卷积,跨行咋解释?
    语音识别和这个不一样,语音是和时间相关的。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2551 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 15:24 PVG 23:24 LAX 08:24 JFK 11:24
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86