Cosecant作者
4年6个月前IP:上海
904101
1楼
第二天~八点(pm)~

查阅了NinaPro的原始论文,ps:他们的官网是真的烂,图片没显示,害我找了好久。

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

另外使用了DB9论文中的角度换算

尝试使用这个转换DB8中的手套数据,并使用UE4进行可视化。  

然而论文里的源码并不能运行,在连续改了两个bug跑出来以后,得到的角度数据没有参考系,等于无法复现。焯! sticker

然后我就寻思了,手套传感器数据通过隐函数映射到手指姿态,虽然论文里的隐函数转换脚本没法用了,但是我可以直接输出传感器数据啊,四舍五入我也得到手指姿态了。绝对不是为了赶论文。 sticker

然后我就快乐的写了一大片代码开始跑上面得到的数据集。


考虑到论文最好不全公开,我就贴下网络结构。PS 目前没调好,不一定能收敛。

class MyNet(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_chan):
        super(MyNet, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.lstm = nn.LSTM(input_size,
                            hidden_size,
                            num_layers,
                            batch_first=True)
        #input tensor of shape (sequence length, batch size, input_size)
        self.fc=nn.Linear(hidden_size, output_chan)
        """ self.fc = nn.Sequential(
            nn.Dropout(droprate),  #Dropout层
            nn.LeakyReLU(),
            nn.Linear(hidden_size, 64),
            nn.LeakyReLU(),
            nn.Linear(64, output_chan)) """

        #把隐藏状态空间用全连接层映射到输出空间。

    def forward(self, x):
        #初始化hidden和cell的states 不赋予初值所以用zeros
        #详情:https://pytorch.org/docs/stable/generated/torch.nn.LSTM.html
        h0 = torch.zeros(self.num_layers, x.size(0),
                         self.hidden_size).to(device)
        c0 = torch.zeros(self.num_layers, x.size(0),
                         self.hidden_size).to(device)
        #LSTM
        output, (hn, cn) = self.lstm(x, (h0, c0))
        #tensor of shape (batch size, sequence length, hidden_size)

        output = self.fc(output[:, -1, :])  #取sequence的最后一个输出hn
        #tensor of shape (batch size, sequence length, hidden_size)

        return output

开始炼丹!

1652116462(1).png

1652116635967.png

这400多w的Loss是怎么来的???

刚开始,我还以为是梯度爆炸了之类的,毕竟我的Loss从几十万到几百万都有,很是奇怪,所以我先从这方面入手

这Loss这么大是不是我网络有问题啊?

询问了大佬后突然发现了一个盲点,我的数据是EMG数据集,用的是LSTM,激活函数默认为tanh,然后EMG数据大概是e-6量级,感觉会有问题,所以做了归一化。

归一化脚本:

def data_scaler(input_list):
    """
    @description  :
    ---------
    @param  :
    -------
    @Returns  :
    -------
    """
    scaler = MinMaxScaler(copy=False)
    matData=input_list[0]
    matFile=input_list[1]
    norm_data={}
    norm_data['emg'] = []

    scaler.fit(matData['emg'])
    norm_data['emg']=scaler.transform(matData['emg'])
    matData['emg']=norm_data['emg']
    sio.savemat(saveDir+matFile, matData)

pool = ThreadPool()
mat_list=[]
for matFile in findAllMat(): 
    matData=sio.loadmat(dataDir+matFile)
    mat_list.append([matData,matFile])
results = pool.map(data_scaler, mat_list)
pool.close()
pool.join()

抽空再试试标准化。

然后继续训练,中间又改小了batch_size,由于Loss是整个batch的Loss和,所以Loss确实小了点,但是也没小多少,归一化以后结果好像没啥变化···不管了,归一化做了是对的,先这样跑吧,只要能收敛就行。

然后我发现了Loss的一个规律

1652116260.png

这玩意一会儿高一会儿低的怎么?

经过分析我发现

大概23680条数据为一个周期,一个文件大概有2292000条  

有0-9个动作,其中0为复位  

每个动作会重复10次  

data_total=2292000  

data_total/9(个动作)/10(10次重复)=25472 非常接近23680的数量级,也就是说动作改变的时候loss会突增突减


那行吧,好像也没啥问题,先跑着。

然后在我的3080跑了一小时之后

e2790b2744788c3bb8d1c72fb93ca99.png

???我的Loss呢!!!

我那么大的Loss,几百万呢?怎么突然就没了?

没了Loss.gif

俺跑了两遍,都是在这里Loss消失,又百度了下。高度怀疑是数据集本身有问题。

经过写脚本定位查找以后,从7个G的数据集里成功揪出来了丢失的数据

mad,这群*人不会做数据集能不能不要做,跑了俩小时直接给我干废了

PL5H{GKQV}`(BJWOQHVTL60.png

又把他们截掉然后重新跑。

脚本贴一下吧,这个nan问题很是花了我一番功夫

import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
import os
from torch.utils.data import Dataset
import torch
from math import isnan
dataDir = './EMG_data/linear/'
saveDir = './EMG_data/nan_deled/'
def findAllMat():
    """
    @description  :找到dataDir下所有的mat文件
    ---------
    @param  :
    -------
    @Returns  :
    -------
    """
    for root,dirs,files in os.walk(dataDir):
        for f in files:
            if(f.split('.')[-1]=="mat"):
                yield f
def readMat(mData, name, del_nan):
    """
    @description  :读取并处理mat文件,找到nan的数据
    ---------
    @param  :mData 数据 name文件名 del_nan是否处理
    -------
    @Returns  :
    -------
    """
    h=-1
    l=-1
    mlist=['emg','glove','rerepetition','restimulus']
    for i in range(0,4):
        foo=mData[mlist[i]]
        if(len(np.where(np.isnan(foo))[0])):
            h=np.where(np.isnan(foo))[0][0] #行数-1(索引)
            l=np.where(np.isnan(foo))[1][0] #列数-1
            #print(name)
            break
    if(h!=-1 and del_nan):
        for i in range(0,4):
            mData[mlist[i]]=mData[mlist[i]][:h,]
        sio.savemat(saveDir+name, mData)    


for matFile in findAllMat():
    matData = sio.loadmat(dataDir + matFile)
    readMat(matData, matFile, True)

最后都整的差不多了,打算挂一晚上,看看能不能跑收敛。

明天更不更看心情了。

评论(1)
7
文号 / 904101

实习会员
名片发私信
学术分 0
总主题 1 帖总回复 1 楼拥有证书:进士 机友 笔友
注册于 2020/01/03 23:51:03最后登录 2026/02/08 23:51:01
主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:上海

个人简介

暂未填写
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的