├── result └── DB2_S1muti2.png ├── __pycache__ └── EMGImg.cpython-36.pyc ├── Util ├── __pycache__ │ ├── FFT.cpython-37.pyc │ ├── FFT.cpython-38.pyc │ ├── SepData.cpython-36.pyc │ ├── SepData.cpython-37.pyc │ ├── function.cpython-36.pyc │ ├── feature_set.cpython-36.pyc │ └── feature_utils.cpython-37.pyc ├── plotUtil.py ├── XFFT.py ├── feature_utils.py ├── function.py ├── txtutil.py ├── FFT.py ├── confusion_matrix.py ├── SepData.py └── feature_set.py ├── Model1D ├── __pycache__ │ ├── Away12CNN1D.cpython-36.pyc │ └── Away12CNN1D.cpython-37.pyc ├── Away12CNN1D.py ├── Train1D.py └── Test1D.py ├── Models ├── DBlayers │ ├── __pycache__ │ │ ├── CBAM.cpython-36.pyc │ │ ├── SENet.cpython-36.pyc │ │ ├── daNet.cpython-36.pyc │ │ └── Attention.cpython-36.pyc │ ├── SENet-keras.py │ ├── SENet.py │ ├── Attention.py │ ├── Unet.py │ ├── CBAM.py │ ├── Densenet.py │ └── daNet.py ├── DBEmgNet │ ├── __pycache__ │ │ ├── emgFile.cpython-36.pyc │ │ └── Away3CBAMNEW.cpython-36.pyc │ ├── DownAway3CBAM.py │ ├── emgFile.py │ └── Away3CBAMNEW.py ├── DBFeaNet │ ├── __pycache__ │ │ └── FeaModel.cpython-36.pyc │ └── FeaModel.py ├── PopularModel │ ├── __pycache__ │ │ ├── Energy.cpython-36.pyc │ │ ├── Vnet.cpython-36.pyc │ │ └── EnergyAndEmg.cpython-36.pyc │ ├── Energy.py │ ├── EnergyAndEmg.py │ ├── Vnet.py │ └── XiaoRong.py ├── TrainModel │ ├── __pycache__ │ │ ├── Train3main.cpython-36.pyc │ │ └── Train3main.cpython-37.pyc │ ├── 1EmgTrain.py │ ├── 1featureTrain.py │ ├── 1EmgFeaTrain.py │ ├── Train3main.py │ ├── EnergyTrain.py │ └── EnergyAndFeaTrain.py ├── DBFeaEmgNet │ ├── __pycache__ │ │ └── FeaEmgFile.cpython-36.pyc │ └── FeaEmgFile.py └── TestModel │ ├── 1CTestMer1.py │ └── 3CTest.py ├── Preprocess ├── __pycache__ │ ├── EnhanceZsc.cpython-37.pyc │ └── Combination.cpython-36.pyc ├── Segment.py ├── SegNor.py ├── DownSample.py ├── Combination.py ├── GetEnergy.py ├── DFactionSeg.py └── EnhanceZsc.py ├── EMGImg.py ├── other ├── rawh5plot.py ├── Sort_dataset.py ├── Wavelet.py ├── Test1.py ├── skconv.py └── ZscoreSegVal.py ├── README.md ├── feature ├── Mark.py ├── STFT.py ├── GetFreFeature.py ├── Shap.py ├── GetTimeFeature.py ├── FeatureMap.py └── GetFeature.py ├── Denoise ├── Butter_low.py └── EMGFilter.py ├── GetRaw.py └── nina_fun.txt /result/DB2_S1muti2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/result/DB2_S1muti2.png -------------------------------------------------------------------------------- /__pycache__/EMGImg.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/__pycache__/EMGImg.cpython-36.pyc -------------------------------------------------------------------------------- /Util/__pycache__/FFT.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Util/__pycache__/FFT.cpython-37.pyc -------------------------------------------------------------------------------- /Util/__pycache__/FFT.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Util/__pycache__/FFT.cpython-38.pyc -------------------------------------------------------------------------------- /Util/__pycache__/SepData.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Util/__pycache__/SepData.cpython-36.pyc -------------------------------------------------------------------------------- /Util/__pycache__/SepData.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Util/__pycache__/SepData.cpython-37.pyc -------------------------------------------------------------------------------- /Util/__pycache__/function.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Util/__pycache__/function.cpython-36.pyc -------------------------------------------------------------------------------- /Util/__pycache__/feature_set.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Util/__pycache__/feature_set.cpython-36.pyc -------------------------------------------------------------------------------- /Util/__pycache__/feature_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Util/__pycache__/feature_utils.cpython-37.pyc -------------------------------------------------------------------------------- /Model1D/__pycache__/Away12CNN1D.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Model1D/__pycache__/Away12CNN1D.cpython-36.pyc -------------------------------------------------------------------------------- /Model1D/__pycache__/Away12CNN1D.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Model1D/__pycache__/Away12CNN1D.cpython-37.pyc -------------------------------------------------------------------------------- /Models/DBlayers/__pycache__/CBAM.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBlayers/__pycache__/CBAM.cpython-36.pyc -------------------------------------------------------------------------------- /Models/DBlayers/__pycache__/SENet.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBlayers/__pycache__/SENet.cpython-36.pyc -------------------------------------------------------------------------------- /Models/DBlayers/__pycache__/daNet.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBlayers/__pycache__/daNet.cpython-36.pyc -------------------------------------------------------------------------------- /Preprocess/__pycache__/EnhanceZsc.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Preprocess/__pycache__/EnhanceZsc.cpython-37.pyc -------------------------------------------------------------------------------- /Models/DBEmgNet/__pycache__/emgFile.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBEmgNet/__pycache__/emgFile.cpython-36.pyc -------------------------------------------------------------------------------- /Preprocess/__pycache__/Combination.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Preprocess/__pycache__/Combination.cpython-36.pyc -------------------------------------------------------------------------------- /Models/DBFeaNet/__pycache__/FeaModel.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBFeaNet/__pycache__/FeaModel.cpython-36.pyc -------------------------------------------------------------------------------- /Models/DBlayers/__pycache__/Attention.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBlayers/__pycache__/Attention.cpython-36.pyc -------------------------------------------------------------------------------- /Models/PopularModel/__pycache__/Energy.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/PopularModel/__pycache__/Energy.cpython-36.pyc -------------------------------------------------------------------------------- /Models/PopularModel/__pycache__/Vnet.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/PopularModel/__pycache__/Vnet.cpython-36.pyc -------------------------------------------------------------------------------- /Models/DBEmgNet/__pycache__/Away3CBAMNEW.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBEmgNet/__pycache__/Away3CBAMNEW.cpython-36.pyc -------------------------------------------------------------------------------- /Models/TrainModel/__pycache__/Train3main.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/TrainModel/__pycache__/Train3main.cpython-36.pyc -------------------------------------------------------------------------------- /Models/TrainModel/__pycache__/Train3main.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/TrainModel/__pycache__/Train3main.cpython-37.pyc -------------------------------------------------------------------------------- /Models/DBFeaEmgNet/__pycache__/FeaEmgFile.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/DBFeaEmgNet/__pycache__/FeaEmgFile.cpython-36.pyc -------------------------------------------------------------------------------- /Models/PopularModel/__pycache__/EnergyAndEmg.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shaw0446/Ninapro_2023/HEAD/Models/PopularModel/__pycache__/EnergyAndEmg.cpython-36.pyc -------------------------------------------------------------------------------- /EMGImg.py: -------------------------------------------------------------------------------- 1 | class EMG(): 2 | def __init__(self, data, label): 3 | self.data = data 4 | self.label = label 5 | 6 | class reEMG(): 7 | def __init__(self, data, label,rep): 8 | self.data = data 9 | self.label = label 10 | self.rep = rep -------------------------------------------------------------------------------- /other/rawh5plot.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | h5 = h5py.File('../data/DB2_S1raw.h5', 'r') 5 | alldata = h5['alldata'] 6 | # h5.close() 7 | data=np.array(alldata) 8 | plt.plot(data[:,0:12]) 9 | 10 | plt.show() 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ninapro_2023 2 | 肌电信号深度学习毕业论文,知网:基于多通道特征融合网络的肌电信号手势识别方法研究 3 | 主要实现文件 4 | (1)GetRaw读取.mat文件存储为h5 5 | (2)EMGFilter信号去噪声 6 | (3)DFactionSeg 对原始信号分割 标准化 划分数据集 7 | (3-2)GetFeature从时间窗信号中提取特征信号,提取哪些特征可以用shap方法进行分析后替换(此步骤为输入是与时域信号和特征信号的双流网络才需要) 8 | (4)TrainModel文件下EmgTrain进行训练生成的模型参数会保留 9 | (5)TestModel文件下的EMGTest进行测试 10 | (6)Util文件夹txtutil方法将测试结果读取精度存入excel中 11 | 其他文件是备份和其他方法的实现,如能量核、12支路,vnt网络,shap方法和特征提取 12 | -------------------------------------------------------------------------------- /Util/plotUtil.py: -------------------------------------------------------------------------------- 1 | 2 | import matplotlib.pyplot as plt 3 | 4 | # 绘制标签等于num的肌电信号所有通道数据在一张图上 5 | def plot_onelabel(data, label, num): 6 | index = [] 7 | for i in range(data[:].shape[0]): 8 | if label[i] == num: 9 | index.append(i) 10 | # plt.axis([0, 200, -0.0005, 0.0005]) 11 | plt.plot(data[index, :]) 12 | plt.show() 13 | 14 | def plot_channel(sig): 15 | for i in range(12): 16 | plt.subplot(12, 1, i + 1) 17 | plt.plot(sig[0:200, i]) 18 | plt.yticks(fontsize=8) 19 | # plt.ylim(-0.0001, 0.0001) 20 | plt.show() 21 | -------------------------------------------------------------------------------- /feature/Mark.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import matplotlib.pyplot as plt 3 | from pyts.image import MarkovTransitionField, GramianAngularField 4 | import cv2 as cv 5 | import numpy as np 6 | import numpy.fft as fft 7 | 8 | 9 | def get_fft_values(y_values, N, f_s): 10 | f_values = np.linspace(0.0, f_s/2.0, N//2) 11 | fft_values_ = fft.fft(y_values) 12 | fft_values = 2.0/N * np.abs(fft_values_[0:N//2]) 13 | return f_values, fft_values 14 | 15 | 16 | for j in range(1, 2): 17 | h5 = h5py.File('F:/DB2/Downfilter/DB2_s' + str(j) + 'down.h5', 'r') 18 | alldata = h5['alldata'][:] 19 | # 动作状态数据分割 肌电子图标准化 20 | temp = (alldata[0:20,0]).reshape(-1,1) 21 | mtf = MarkovTransitionField(image_size=1) 22 | X_mtf = mtf.fit_transform(temp) 23 | print() -------------------------------------------------------------------------------- /Denoise/Butter_low.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import scipy.signal as signal 4 | import matplotlib.pyplot as plt 5 | import nina_funcs as nf 6 | 7 | 8 | 9 | 10 | if __name__ == '__main__': 11 | for j in range(1, 2): 12 | df1 = pd.read_hdf('D:/Pengxiangdong/ZX/DB2/data/raw/DB2_s' + str(j) + 'raw.h5', 'df') 13 | dfemg_band = nf.filter_data(data=df1, f=(10, 500), butterworth_order=4, btype='bandpass') 14 | dfemg_notch = nf.notch_filter(data=dfemg_band, f0=50, Q=30, fs=2000) 15 | # 存储为h5文件 16 | dfemg_notch.to_hdf('D:/Pengxiangdong/ZX/DB2/data/filter/DB2_s' + str(j) + 'filter.h5', format='table',key='df', mode='w', complevel=9, complib='blosc') 17 | 18 | # file = h5py.File('F:/DB2/filter/DB2_s' + str(j) + 'filter.h5', 'w') 19 | # file.create_dataset('alldata', data=(alldata).astype('float32')) 20 | # file.close() -------------------------------------------------------------------------------- /Denoise/EMGFilter.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import scipy.signal as signal 4 | import matplotlib.pyplot as plt 5 | import nina_funcs as nf 6 | 7 | 8 | 9 | 10 | if __name__ == '__main__': 11 | for j in range(1, 41): 12 | df1 = pd.read_hdf('D:/Pengxiangdong/ZX/DB2/data/restimulus/reraw/DB2_s' + str(j) + 'raw.h5', 'df') 13 | dfemg_band = nf.refilter_data(data=df1, f=(10, 500), butterworth_order=4, btype='bandpass') 14 | dfemg_notch = nf.notch_refilter(data=dfemg_band, f0=50, Q=30, fs=2000) 15 | # 存储为h5文件 16 | dfemg_notch.to_hdf('D:/Pengxiangdong/ZX/DB2/data/restimulus/refilter/DB2_s' + str(j) + 'filter.h5', format='table',key='df', mode='w', complevel=9, complib='blosc') 17 | 18 | # file = h5py.File('F:/DB2/filter/DB2_s' + str(j) + 'filter.h5', 'w') 19 | # file.create_dataset('alldata', data=(alldata).astype('float32')) 20 | # file.close() -------------------------------------------------------------------------------- /other/Sort_dataset.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Oct 21 13:44:03 2020 4 | @author: zelin 5 | """ 6 | import numpy as np 7 | import h5py 8 | 9 | type_names = ['a','E','F','I','j','L','N','R','V'] 10 | fdataset = np.zeros((1,340+1)) 11 | for i in range(len(type_names)): 12 | type_name = type_names[i] 13 | ##### Load data ##### 14 | data_path = 'data/S1_E1_A1.mat'.format(type_name) 15 | print(data_path) 16 | # mat = h5py.File(data_path) 17 | # keys = ''.join(list(mat.keys())) 18 | # fmat = np.transpose(mat[keys]) 19 | # m_in = fmat.min() 20 | # m_ax = fmat.max() 21 | # ffmat = (fmat-m_in)/(m_ax-m_in) 22 | # 23 | # label_col = np.ones((ffmat.shape[0],1))*(i) 24 | # class_dataset = np.c_[ffmat,label_col] 25 | # fdataset = np.r_[fdataset,class_dataset] 26 | # 27 | # np.save('dataset.npy',fdataset[1:,:]) 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Preprocess/Segment.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import numpy as np 4 | import scipy.signal as signal 5 | import nina_funcs as nf 6 | 7 | 8 | train_reps = [1, 3, 4, 6] 9 | test_reps = [2, 5] 10 | gestures = list(range(1, 50)) 11 | 12 | 13 | 14 | 15 | for j in range(1, 2): 16 | df = pd.read_hdf('D:/Pengxiangdong/ZX/DB2/data/stimulus/filter/DB2_s' + str(j) + 'filter.h5', 'df') 17 | 18 | '''step2: 滑动窗口分割''' 19 | emg, label, rep = nf.windowing(df, reps=[], gestures=gestures, win_len=400, win_stride=100) 20 | # x_test, y_test, r_test = nf.windowing(df, reps=test_reps, gestures=gestures, win_len=20, win_stride=1) 21 | 22 | # 存储为h5文件 23 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/stimulus/TimeSeg/DB2_s' + str(j) + 'Seg.h5', 'w') 24 | file.create_dataset('emg', data=emg.astype('float32')) 25 | file.create_dataset('label', data=label.astype('int32')) 26 | file.create_dataset('rep', data=rep.astype('int32')) 27 | file.close() 28 | 29 | print('******************DB2_s' + str(j) + '分割完成***********************') 30 | 31 | 32 | -------------------------------------------------------------------------------- /Util/XFFT.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | 6 | 7 | def get_plotsigfre(sig,title = None): 8 | start= 0 9 | end=len(sig) 10 | iSampleRate = 2000 # 采样频率 11 | signal = sig[start:end] 12 | iSampleCount = signal.shape[0] # 采样数 13 | t = np.linspace(0, iSampleCount / iSampleRate, iSampleCount) 14 | 15 | xFFT = np.abs(np.fft.rfft(signal) / iSampleCount) # 快速傅里叶变换 16 | xFreqs = np.linspace(0, iSampleRate / 2, int(iSampleCount / 2) + 1) 17 | 18 | plt.figure(figsize=(10, 6)) 19 | 20 | ax0 = plt.subplot(211) # 画时域信号 21 | plt.title(title) 22 | ax0.set_xlabel("Time(s)") 23 | # plt.xlim(0, 800) 24 | ax0.set_ylabel("Amp(μV)") 25 | ax0.plot(t, signal) 26 | 27 | ax1 = plt.subplot(212) # 画频域信号-频谱 28 | ax1.set_xlabel("Freq(Hz)") 29 | ax1.set_ylabel("Power") 30 | ax1.plot(xFreqs, xFFT) 31 | plt.show() 32 | 33 | if __name__ == '__main__': 34 | h5 = h5py.File('../data/DB2_S1raw.h5', 'r') 35 | alldata = h5['alldata'] 36 | emg=alldata[:,0] 37 | get_plotsigfre(emg) 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /GetRaw.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import scipy.io as scio 3 | import numpy as np 4 | import nina_funcs as nf 5 | import pandas as pd 6 | 7 | dir='D:/Pengxiangdong/ZX/DB2/Ninapro' 8 | 9 | if __name__ == '__main__': 10 | for j in range(1, 41): 11 | df1 = nf.get_redata(dir + '\DB2_s' + str(j), 'S' + str(j) + '_E1_A1.mat') 12 | df2 = nf.get_redata(dir + '\DB2_s' + str(j), 'S' + str(j) + '_E2_A1.mat') 13 | df3 = nf.get_redata(dir + '\DB2_s' + str(j), 'S' + str(j) + '_E3_A1.mat') 14 | 15 | dfall = pd.concat([df1, df2, df3],ignore_index=True) 16 | # 考虑数据放大到1 17 | dfmax = dfall.copy(deep=True) 18 | dfmax.iloc[:, :12] = dfmax.iloc[:, :12] 19 | df = dfmax.astype(np.float32) 20 | 21 | df.to_hdf('D:/Pengxiangdong/ZX/DB2/data/restimulus/reraw/DB2_s' + str(j) + 'raw.h5',format='table',key='df', mode='w',complevel=9, complib='blosc') 22 | 23 | print('******************DB2_s' + str(j) + '读取完成***********************') 24 | 25 | # file = h5py.File('F:/DB2/raw/DB2_s' + str(j) + 'raw.h5', 'w') 26 | # file.create_dataset('alldata', data=(dfall).astype('float32')) 27 | # file.close() 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Preprocess/SegNor.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import numpy as np 4 | import scipy.signal as signal 5 | import nina_funcs as nf 6 | 7 | 8 | train_reps = [1, 3, 4, 6] 9 | test_reps = [2, 5] 10 | gestures = list(range(1, 50)) 11 | 12 | 13 | 14 | #此为测试不做动作分割的影响,效果不好 废弃 15 | for j in range(1, 2): 16 | df = pd.read_hdf('D:/Pengxiangdong/ZX/DB2/data/stimulus/raw/DB2_s' + str(j) + 'raw.h5', 'df') 17 | 18 | df1 = nf.normalise(df.copy(deep=True), train_reps) 19 | 20 | df2 = df1.copy(deep=True) 21 | # df2 = df2.astype(np.float32) 22 | 23 | '''step2: 滑动窗口分割''' 24 | emg, label, rep = nf.windowing(df2, reps=[], gestures=gestures, win_len=400, win_stride=100) 25 | # x_test, y_test, r_test = nf.windowing(df, reps=test_reps, gestures=gestures, win_len=20, win_stride=1) 26 | 27 | # 存储为h5文件 28 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/stimulus/TimeSeg/DB2_s' + str(j) + 'SegNor.h5', 'w') 29 | file.create_dataset('emg', data=emg.astype('float32')) 30 | file.create_dataset('label', data=label.astype('int32')) 31 | file.create_dataset('rep', data=rep.astype('int32')) 32 | file.close() 33 | 34 | print('******************DB2_s' + str(j) + '分割完成***********************') 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Util/feature_utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def featureRMS(data): 5 | return np.sqrt(np.mean(data ** 2, axis=0)) 6 | 7 | 8 | def featureMAV(data): 9 | return np.mean(np.abs(data), axis=0) 10 | 11 | 12 | def featureWL(data): 13 | return np.sum(np.abs(np.diff(data, axis=0)), axis=0) / data.shape[0] 14 | 15 | 16 | def featureZC(data, threshold=10e-7): 17 | numOfZC = [] 18 | channel = data.shape[1] 19 | length = data.shape[0] 20 | 21 | for i in range(channel): 22 | count = 0 23 | for j in range(1,length): 24 | diff = data[j,i] - data[j-1,i] 25 | mult = data[j,i] * data[j-1,i] 26 | 27 | if np.abs(diff)>threshold and mult<0: 28 | count=count+1 29 | numOfZC.append(count/length) 30 | return np.array(numOfZC) 31 | 32 | 33 | def featureSSC(data, threshold=10e-7): 34 | numOfSSC = [] 35 | channel = data.shape[1] 36 | length = data.shape[0] 37 | 38 | for i in range(channel): 39 | count = 0 40 | for j in range(2, length): 41 | diff1 = data[j, i] - data[j - 1, i] 42 | diff2 = data[j - 1, i] - data[j - 2, i] 43 | sign = diff1 * diff2 44 | 45 | if sign > 0: 46 | if (np.abs(diff1) > threshold or np.abs(diff2) > threshold): 47 | count = count + 1 48 | numOfSSC.append(count / length) 49 | return np.array(numOfSSC) 50 | -------------------------------------------------------------------------------- /Models/DBlayers/SENet-keras.py: -------------------------------------------------------------------------------- 1 | """ 2 | Clean and simple Keras implementation of SE block as described in: 3 | - [Squeeze-and-Excitation Networks](https://arxiv.org/abs/1709.01507) 4 | 5 | Python 3. 6 | """ 7 | 8 | from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Activation, Reshape, Permute, multiply 9 | 10 | 11 | def SEBlock(se_ratio=16, activation="relu", data_format='channels_last', ki="he_normal"): 12 | ''' 13 | se_ratio : ratio for reduce the filter number of first Dense layer(fc layer) in block 14 | activation : activation function that of first dense layer 15 | data_format : channel axis is at the first of dimension or the last 16 | ki : kernel initializer 17 | ''' 18 | 19 | def f(input_x): 20 | channel_axis = -1 if data_format == 'channels_last' else 1 21 | input_channels = input_x._keras_shape[channel_axis] 22 | 23 | reduced_channels = input_channels // se_ratio 24 | 25 | # Squeeze operation 26 | x = GlobalAveragePooling2D()(input_x) 27 | x = Reshape(1, 1, input_channels)(x) if data_format == 'channels_first' else x 28 | x = Dense(reduced_channels, kernel_initializer=ki)(x) 29 | x = Activation(activation)(x) 30 | # Excitation operation 31 | x = Dense(input_channels, kernel_initializer=ki, activation='sigmoid')(x) 32 | x = Permute(dims=(3, 1, 2))(x) if data_format == 'channels_first' else x 33 | x = multiply([input_x, x]) 34 | 35 | return x 36 | 37 | return f -------------------------------------------------------------------------------- /Util/function.py: -------------------------------------------------------------------------------- 1 | import math 2 | import h5py 3 | import pandas as pd 4 | import numpy as np 5 | 6 | 7 | 8 | def get_threeSet(emg, label, rep_arr, rep_vali): 9 | train_reps = [1, 3, 4, 6] 10 | test_reps = [2, 5] 11 | #从训练集剔除验证集 12 | train_reps.remove(rep_vali) 13 | x = [np.where(rep_arr[:] == rep) for rep in test_reps] 14 | indices = np.squeeze(np.concatenate(x, axis=-1)) 15 | emg_test = emg[indices, :] 16 | label_test = label[indices] 17 | rep_test=rep_arr[indices] 18 | x = [np.where(rep_arr[:] == rep_vali)] 19 | indices2 = np.squeeze(np.concatenate(x, axis=-1)) 20 | emg_vali = emg[indices2, :] 21 | label_vali = label[indices2] 22 | rep_vali=rep_arr[indices2] 23 | x = [np.where(rep_arr[:] == rep) for rep in train_reps] 24 | indices3 = np.squeeze(np.concatenate(x, axis=-1)) 25 | emg_train = emg[indices3, :] 26 | label_train = label[indices3] 27 | rep_train=rep_arr[indices3] 28 | 29 | return emg_train, emg_vali, emg_test, label_train, label_vali, label_test 30 | 31 | 32 | def get_twoSet(emg, label, rep_arr): 33 | train_reps = [1, 3, 4, 6] 34 | test_reps = [2, 5] 35 | x = [np.where(rep_arr[:] == rep) for rep in test_reps] 36 | indices = np.squeeze(np.concatenate(x, axis=-1)) 37 | emg_test = emg[indices, :] 38 | label_test = label[indices] 39 | x = [np.where(rep_arr[:] == rep) for rep in train_reps] 40 | indices3 = np.squeeze(np.concatenate(x, axis=-1)) 41 | emg_train = emg[indices3, :] 42 | label_train = label[indices3] 43 | 44 | return emg_train, emg_test, label_train, label_test 45 | 46 | # if __name__ == '__main__': 47 | # train_reps = [1, 3, 4, 6] 48 | # test_reps = 3 49 | # train_reps.remove(test_reps) 50 | # train_reps 51 | -------------------------------------------------------------------------------- /other/Wavelet.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | 3 | import matplotlib.pyplot as plt 4 | import pywt 5 | import math 6 | import numpy as np 7 | import h5py 8 | 9 | h5 = h5py.File('../data/DB2_S1_image200.h5', 'r') 10 | emg = h5['imageData'] 11 | imageLabel= h5['imageLabel'] 12 | data = [] 13 | coffs = [] 14 | 15 | for i in range(len(emg)): 16 | for j in range(200): 17 | Y = emg[i, j, 1] 18 | data.append(Y) 19 | #create wavelet object and define parameters 20 | w = pywt.Wavelet('db8') #选用Daubechies8小波 21 | maxlev = pywt.dwt_max_level(len(data),w.dec_len) 22 | print("maximum level is"+str(maxlev)) 23 | threshold= 0.04 #Threshold for filtering 24 | 25 | #Decompose into wavelet components,to the level selected: 26 | coffs = pywt.wavedec(data,'db8',level=maxlev) #将信号进行小波分解 27 | 28 | for i in range(1,len(coffs)): 29 | temp = pywt.threshold(coffs[i],threshold*max(coffs[i])) 30 | coffs[i] = temp 31 | datarec = pywt.waverec(coffs,'db8')#将信号进行小波重构 32 | 33 | mintime = 0 34 | maxtime = mintime+len(data) 35 | windowstep = 200 36 | print(mintime,maxtime) 37 | for i in range(int(maxtime/windowstep)): 38 | plt.figure() 39 | plt.subplot(3,1,1) 40 | plt.plot(data[i*windowstep:(i+1)*windowstep]) 41 | plt.xlabel('time (s)') 42 | plt.ylabel('microvolts (uV)') 43 | plt.title("Raw signal") 44 | plt.subplot(3, 1, 2) 45 | plt.plot(datarec[i*windowstep:(i+1)*windowstep]) 46 | plt.xlabel('time (s)') 47 | plt.ylabel('microvolts (uV)') 48 | plt.title("De-noised signal using wavelet techniques") 49 | plt.subplot(3, 1, 3) 50 | plt.plot(data[i*windowstep:(i+1)*windowstep]-datarec[i*windowstep:(i+1)*windowstep]) 51 | plt.xlabel('time (s)') 52 | plt.ylabel('error (uV)') 53 | plt.tight_layout() 54 | plt.show() 55 | print(maxtime/windowstep) 56 | 57 | -------------------------------------------------------------------------------- /Util/txtutil.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import pandas as pd 3 | import numpy as np 4 | import xlwt 5 | import re 6 | 7 | def txt_xls(filename, xlsname): 8 | start_row = 0 9 | start_col = 0 10 | f = open(filename,encoding = 'utf-8') 11 | xls = xlwt.Workbook(encoding = 'utf-8') 12 | # 生成excel的方法,声明excel 13 | sheet = xls.add_sheet('sheet1') 14 | row_excel = start_row 15 | for line in f: 16 | line = line.strip('\n') 17 | line = line.split() 18 | 19 | print(line) 20 | 21 | col_excel = start_col 22 | len_line = len(line) 23 | for j in range(len_line): 24 | # print(line[j]) 25 | sheet.write(row_excel, col_excel, line[j]) 26 | col_excel += 1 27 | xls.save(xlsname) # 保存为xls文件 28 | 29 | row_excel += 1 30 | f.close() 31 | 32 | rootdata="D:/Pengxiangdong/ZX/DB2/result/restimulus2/" 33 | #从原始的多个txt文件导入xls 34 | if __name__ == '__main__': 35 | 36 | for j in range(1,41): 37 | newdata=[] 38 | data=[] 39 | filepath=rootdata+"346-1-25/DB2_s"+str(j)+"emgfea.txt" 40 | with open(filepath,encoding='utf-8',) as txtfile: 41 | line=txtfile.readlines() 42 | for i,rows in enumerate(line): 43 | if i in [52,53] : #指定数据哪几行 44 | data.append(rows) 45 | txtfile.close() 46 | newdata=(data[0]+data[1]).replace("\n", "") 47 | # #写入 48 | path=rootdata+"346-1Statistics.txt" 49 | with open(path, "a", ) as f: 50 | f.writelines(newdata+'\n') 51 | f.close() 52 | #写入excel 53 | xlsname=rootdata+"346-1Statistics.xls" 54 | txt_xls(path,xlsname) 55 | 56 | 57 | 58 | #从汇总的txt文件导入xls 59 | # if __name__ == '__main__': 60 | # path="E:/360MoveData/Users/Administrator/Desktop/Statistics.txt" 61 | # # 写入excel 62 | # xlsname = "E:/360MoveData/Users/Administrator/Desktop/Statistics.xls" 63 | # txt_xls(path, xlsname) 64 | -------------------------------------------------------------------------------- /Model1D/Away12CNN1D.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import backend as K 3 | from tensorflow.keras import layers as KL 4 | 5 | def BConv(layer): 6 | x = KL.Conv1D(filters=64, kernel_size=8, strides=1, padding='same')(layer) 7 | x = KL.Activation('relu')(x) 8 | x = KL.BatchNormalization()(x) 9 | x = KL.Conv1D(filters=128, kernel_size=2, strides=1, padding='same')(x) 10 | x = KL.Activation('relu')(x) 11 | x = KL.BatchNormalization()(x) 12 | return x 13 | 14 | 15 | 16 | def Away12reluBNCNN1D(): 17 | input1 = KL.Input(shape=(400, 1)) 18 | input2 = KL.Input(shape=(400, 1)) 19 | input3 = KL.Input(shape=(400, 1)) 20 | input4 = KL.Input(shape=(400, 1)) 21 | input5 = KL.Input(shape=(400, 1)) 22 | input6 = KL.Input(shape=(400, 1)) 23 | input7 = KL.Input(shape=(400, 1)) 24 | input8 = KL.Input(shape=(400, 1)) 25 | input9 = KL.Input(shape=(400, 1)) 26 | input10 = KL.Input(shape=(400, 1)) 27 | input11 = KL.Input(shape=(400, 1)) 28 | input12 = KL.Input(shape=(400, 1)) 29 | 30 | output1 = BConv(input1) 31 | output2 = BConv(input2) 32 | output3 = BConv(input3) 33 | output4 = BConv(input4) 34 | output5 = BConv(input5) 35 | output6 = BConv(input6) 36 | output7 = BConv(input7) 37 | output8 = BConv(input8) 38 | output9 = BConv(input9) 39 | output10 = BConv(input10) 40 | output11 = BConv(input11) 41 | output12 = BConv(input12) 42 | 43 | c = KL.Concatenate(axis=-1)([output1, output2,output3, output4,output5, output6,output7, output8,output9, output10,output11,output12]) 44 | X = KL.GlobalAvgPool1D()(c) 45 | X = KL.Dense(128, activation='relu')(X) 46 | X = KL.Dropout(0.5)(X) 47 | s = KL.Dense(49, activation='softmax')(X) 48 | model = tf.keras.Model(inputs=[input1, input2,input3, input4,input5, input6,input7, input8,input9, input10,input11,input12], outputs=s) 49 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 50 | loss='categorical_crossentropy', metrics=['accuracy']) 51 | return model 52 | -------------------------------------------------------------------------------- /feature/STFT.py: -------------------------------------------------------------------------------- 1 | import biosppy 2 | import h5py 3 | import scipy 4 | import scipy.signal as signal 5 | import matplotlib.pyplot as plt 6 | import numpy as np 7 | 8 | from Preprocess.Segment import actionSegment 9 | 10 | 11 | def stft(sig, **params): 12 | ''' 13 | 快速傅里叶变换时时频域图像 14 | :param sig: 输入信号 15 | :param params: {fs:采样频率; 16 | window:窗。默认为汉明窗; 17 | nperseg: 每个段的长度,默认为256, 18 | noverlap:重叠的点数。指定值时需要满足COLA约束。默认是窗长的一半, 19 | nfft:fft长度, 20 | detrend:(str、function或False)指定如何去趋势,默认为Flase,不去趋势。 21 | return_onesided:默认为True,返回单边谱。 22 | boundary:默认在时间序列两端添加0 23 | padded:是否对时间序列进行填充0(当长度不够的时候), 24 | axis:可以不必关心这个参数} 25 | :return: f:采样频率数组;t:段时间数组;Zxx:STFT结果 26 | Zxx返回的是二维数组,每一列数据某一时间段的频谱,每一行表示某一频率的不同时间的复数。 27 | ''' 28 | f, t, zxx = signal.stft(sig, **params) 29 | return f, t, zxx 30 | 31 | def stft_specgram(sig, picname=None, **params): #picname是给图像的名字,为了保存图像 32 | f, t, zxx = stft(sig, fs=2000, nperseg=128) 33 | plt.pcolormesh(t, f, np.abs(zxx), shading='auto') 34 | plt.colorbar() 35 | plt.title('STFT Magnitude') 36 | plt.ylabel('Frequency [Hz]') 37 | plt.xlabel('Time [sec]') 38 | plt.tight_layout() 39 | plt.show() 40 | # if picname is not None: 41 | # plt.savefig( str(picname) + '.jpg') #保存图像 42 | # plt.clf() #清除画布 43 | return f, t, zxx 44 | 45 | 46 | 47 | if __name__ == '__main__': 48 | for j in range(1, 2): 49 | h5 = h5py.File('F:/DB2/raw/DB2_s' + str(j) + 'raw.h5', 'r') 50 | alldata = h5['alldata'][:] 51 | seglist = actionSegment(alldata, 1, 12) 52 | # bnlist = bnsegment(seglist)i 53 | stftarr=[] 54 | for k in range(6): 55 | iemg = seglist[k].data 56 | for m in range(12): 57 | f, t, zxx=signal.spectrogram(iemg[0:400, m],fs=2000,noverlap=128) 58 | stftarr.append(f) 59 | print() 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /feature/GetFreFeature.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import numpy as np 4 | from sklearn import preprocessing 5 | import scipy.signal as signal 6 | import matplotlib.pyplot as plt 7 | import nina_funcs as nf 8 | 9 | from Util.function import get_twoSet 10 | 11 | train_reps = [1, 3, 4, 6] 12 | test_reps = [2, 5] 13 | # gestures = list(range(1,50)) 14 | 15 | 16 | def fea_transpose(data): 17 | # 为了便于归一化,对矩阵进行转置 18 | arr_T = np.transpose(np.array(data)) 19 | sc_fea = preprocessing.StandardScaler().fit_transform(arr_T) 20 | arr_fea = np.transpose(sc_fea) 21 | return arr_fea 22 | 23 | root_data = 'D:/Pengxiangdong/ZX/' 24 | if __name__ == '__main__': 25 | for j in range(1, 2): 26 | file = h5py.File(root_data + 'DB2/data/stimulus/Seg/DB2_s' + str(j) + 'Seg.h5', 'r') 27 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 28 | file.close() 29 | emg_train, emg_test, label_train, label_test = get_twoSet(emg, label, rep) 30 | 31 | '''step2: 选择特征组合和归一化''' 32 | # 选择特征组合 33 | # frequency_features = ["fr", "mnp", "mnf", "mdf", "pkf"] 34 | 35 | fea_train = nf.frequency_features_extractor(shape=(emg_train.shape[0], -1), data=emg_train) 36 | fea_test = nf.frequency_features_extractor(shape=(emg_test.shape[0], -1), data=emg_test) 37 | 38 | fea_all = np.concatenate([fea_train, fea_test], axis=0) 39 | # 40 | ss = preprocessing.StandardScaler() 41 | ss.fit(fea_train) 42 | sc_train = ss.transform(fea_train) 43 | sc_test = ss.transform(fea_test) 44 | 45 | # fea_all = np.concatenate([sc_train, sc_test], axis=0) 46 | # 存储为h5文件 47 | file = h5py.File(root_data + 'DB2/data/stimulus/Fea/DB2_s' + str(j) + '15fea.h5', 'w') 48 | file.create_dataset('fea_all', data=fea_all.astype('float32')) 49 | file.create_dataset('fea_label', data=label.astype('int')) 50 | file.create_dataset('fea_rep', data=rep.astype('int')) 51 | file.close() 52 | print('******************DB2_s' + str(j) + '分割完成***********************') -------------------------------------------------------------------------------- /Preprocess/DownSample.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import numpy as np 3 | import wfdb 4 | from scipy.signal import resample 5 | from wfdb import processing 6 | import pandas as pd 7 | import nina_funcs as nf 8 | 9 | 10 | def downsample(data, oldFS, newFS): 11 | """ 12 | Resample data from oldFS to newFS using the scipy 'resample' function. 13 | 14 | Parameters 15 | ---------- 16 | data : instance of pandas.core.DataFrame 17 | Data to resample. 18 | oldFS : float 19 | The sampling frequency of data. 20 | newFS : float 21 | The new sampling frequency. 22 | 23 | Returns: 24 | 25 | newData : instance of pandas.DataFrame 26 | The downsampled dataset. 27 | """ 28 | 29 | newNumSamples = int((data.shape[0] / oldFS) * newFS) 30 | newData = pd.DataFrame(resample(data, newNumSamples)) 31 | return newData 32 | 33 | 34 | if __name__ == '__main__': 35 | for j in range(1,2): 36 | df = pd.read_hdf('D:/Pengxiangdong/ZX/DB2/data/raw/DB2_s' + str(j) + 'raw.h5', 'df') 37 | data = np.array(df) 38 | channel = 12 39 | index = [] 40 | tempemg = [] 41 | templabel = [] 42 | temprep = [] 43 | #数据降采样 44 | for i in range(channel): 45 | index = processing.resample_sig(data[:, i], fs=2000, fs_target=100) 46 | downlabs = index[1] 47 | #标签降采样 48 | for m in downlabs: 49 | tempemg.append(data[int(m), :channel]) 50 | 51 | for m in downlabs: 52 | templabel.append(data[int(m), channel]) 53 | 54 | for m in downlabs: 55 | temprep.append(data[int(m), channel + 1]) 56 | downemg = (np.array(tempemg)) 57 | label = (np.array(templabel)) 58 | rep = np.array(temprep) 59 | # 转为DataFrame存储 60 | df_down = pd.DataFrame(downemg) 61 | df_down['stimulus'] = label 62 | df_down['repetition'] = rep 63 | 64 | # 存储为h5文件 65 | df_down.to_hdf('D:/Pengxiangdong/ZX/DB2/data/df_down/DB2_s' + str(j) + 'down.h5', format='table', key='df', mode='w', complevel=9, complib='blosc') 66 | print() 67 | -------------------------------------------------------------------------------- /Util/FFT.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import numpy as np#导入一个数据处理模块 3 | import pylab as plt#导入一个绘图模块,matplotlib下的模块 4 | from numpy.fft import fft 5 | import seaborn as sns 6 | 7 | 8 | # 傅里叶变换频谱 横轴频率纵轴能量 9 | def plot_FFT(signal): 10 | signal = signal 11 | iSampleCount = signal.shape[0] # 采样数 12 | iSampleRate = 2000 13 | yf1 = np.abs(np.fft.rfft(signal) / iSampleCount) # 快速傅里叶变换 14 | xf1 = np.linspace(0, iSampleRate / 2, int(iSampleCount / 2) + 1) #由于对称性,只取一半区间 15 | plt.figure(figsize=(12, 8), dpi=100) 16 | plt.subplot(211) 17 | plt.plot(signal) 18 | plt.title('Original wave') 19 | plt.subplot(212) 20 | plt.plot(xf1,yf1) 21 | plt.xlabel("Freq(Hz)") 22 | plt.title('FFT of Mixed wave') 23 | plt.show() 24 | 25 | def plot_OnlyFFT(sig): 26 | sig=sig 27 | iSampleCount = sig.shape[0] # 采样数 28 | iSampleRate = 2000 29 | yf1 = np.abs(np.fft.rfft(sig) / iSampleCount) # 快速傅里叶变换 30 | xf1 = np.linspace(0, iSampleRate / 2, int(iSampleCount / 2) + 1) # 由于对称性,只取一半区间 31 | plt.figure(figsize=(12, 8), dpi=100) 32 | plt.plot(xf1, yf1) 33 | plt.xlabel("Freq(Hz)") 34 | plt.title('FFT of Mixed wave') 35 | plt.show() 36 | 37 | #以秒为单位 38 | def get_plotsigfre(sig,title = None): 39 | iSampleRate = 2000 # 采样频率 40 | iSampleCount = sig.shape[0] # 采样数 41 | t = np.linspace(0, iSampleCount / iSampleRate, iSampleCount) 42 | xFFT = np.abs(np.fft.rfft(sig) / iSampleCount) # 快速傅里叶变换 43 | xFreqs = np.linspace(0, iSampleRate / 2, int(iSampleCount / 2) + 1) ##对称性只取一半 44 | plt.figure(figsize=(12, 8), dpi=100) 45 | 46 | ax0 = plt.subplot(211) # 画时域信号 47 | plt.title(title) 48 | ax0.set_xlabel("Time(s)") 49 | # plt.xlim(0, 800) 50 | ax0.set_ylabel("Amp(μV)") 51 | ax0.plot(t, sig) 52 | 53 | ax1 = plt.subplot(212) # 画频域信号-振幅谱 xFreqs为频率, xFFT为能量 54 | ax1.set_xlabel("Freq(Hz)") 55 | ax1.set_ylabel("Power") 56 | ax1.plot(xFreqs, xFFT) 57 | sns.set() 58 | plt.show() 59 | 60 | 61 | 62 | 63 | 64 | if __name__ == '__main__': 65 | for j in range(1,2): 66 | h5 = h5py.File('F:/DB2/reraw/DB2_s' + str(j) + 'reraw.h5', 'r') 67 | alldata = h5['alldata'] 68 | plot_FFT(alldata[12000:12400,1]) -------------------------------------------------------------------------------- /feature/Shap.py: -------------------------------------------------------------------------------- 1 | import sklearn 2 | import shap 3 | import h5py 4 | import pandas as pd 5 | import numpy as np 6 | import xgboost as xgb 7 | import matplotlib.pyplot as plt 8 | import nina_funcs as nf 9 | 10 | from Util.function import get_twoSet 11 | 12 | root_data = 'D:/Pengxiangdong/ZX/' 13 | for j in range(1, 2): 14 | feaFile = h5py.File(root_data + 'DB2/data/stimulus/Fea/DB2_s' + str(j) + 'frefea.h5', 'r') 15 | # 将六次重复手势分开存储 16 | fea_all, fea_label, fea_rep = feaFile['fea_all'][:], feaFile['fea_label'][:], feaFile['fea_rep'][:] 17 | feaFile.close() 18 | 19 | fea_train, fea_test, feay_train, feay_test = get_twoSet(fea_all, fea_label, fea_rep ) 20 | 21 | fea_train = fea_train.reshape(fea_train.shape[0], -1, 12) 22 | fea_test = fea_test.reshape(fea_test.shape[0], -1, 12) 23 | 24 | ch = 1 25 | temp = fea_train[:, :, ch - 1] 26 | temp = temp.reshape(temp.shape[0], -1) 27 | 28 | temp2 = fea_test[:, :, ch - 1] 29 | temp2 = temp2.reshape(temp2.shape[0], -1) 30 | 31 | 32 | # fea_names = [ "iemg","wamp","mav","aac"] 33 | # fea_names = ["iemg", "rms", "entropy", "kurtosis", "zero_cross", "mean", "median", "wl", "ssc", "wamp"] 34 | fea_names =["fr", "mnp", "mnf", "mdf", "pkf"] 35 | model = xgb.XGBClassifier(eval_metric='mlogloss').fit(temp, feay_train) 36 | explainer = shap.TreeExplainer(model) 37 | shap_values = explainer.shap_values(temp) 38 | shap_values = np.array(shap_values) 39 | shap.plots.waterfall(shap_values) 40 | 41 | # shap.summary_plot(shap_values, temp, 42 | # plot_type="bar", 43 | # feature_names=fea_names, 44 | # max_display=10, 45 | # title="ch"+str(ch), 46 | # show=True) 47 | 48 | 49 | # # select a set of background examples to take an expectation over 50 | # background = temp[np.random.choice(temp.shape[0], 100, replace=False)] 51 | # 52 | # # explain predictions of the model on three images 53 | # e = shap.DeepExplainer(model, background) 54 | # # ...or pass tensors directly 55 | # # e = shap.DeepExplainer((model.layers[0].input, model.layers[-1].output), background) 56 | # shap_values = e.shap_values(x_test[1:5]) -------------------------------------------------------------------------------- /feature/GetTimeFeature.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import numpy as np 4 | from sklearn import preprocessing 5 | import scipy.signal as signal 6 | import matplotlib.pyplot as plt 7 | import nina_funcs as nf 8 | 9 | from Util.function import get_twoSet 10 | 11 | train_reps = [1, 3, 4, 6] 12 | test_reps = [2, 5] 13 | # gestures = list(range(1,50)) 14 | 15 | def fea_transpose(data): 16 | # 为了便于归一化,对矩阵进行转置 17 | arr_T = np.transpose(np.array(data)) 18 | sc_fea = preprocessing.StandardScaler().fit_transform(arr_T) 19 | arr_fea = np.transpose(sc_fea) 20 | return arr_fea 21 | 22 | root_data = 'D:/Pengxiangdong/ZX/' 23 | if __name__ == '__main__': 24 | for j in range(1, 2): 25 | file = h5py.File(root_data + 'DB2/data/stimulus/Seg/DB2_s' + str(j) + 'Seg.h5', 'r') 26 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 27 | file.close() 28 | emg_train, emg_test, label_train, label_test = get_twoSet(emg, label, rep) 29 | 30 | '''step2: 选择特征组合和归一化''' 31 | # 选择特征组合 32 | 33 | features = [nf.iemg, nf.rms, nf.entropy, nf.kurtosis, nf.zero_cross, nf.mean, nf.median, nf.wl, nf.ssc,nf.wamp] 34 | fea_train1 = nf.feature_extractor(features=features, shape=(emg_train.shape[0], -1), data=emg_train) 35 | fea_test1 = nf.feature_extractor(features=features, shape=(emg_test.shape[0], -1), data=emg_test) 36 | 37 | 38 | 39 | # fea_all = np.concatenate([fea_train, fea_test], axis=0) 40 | 41 | '''!!!正式网络训练过程特征都做了归一化''' 42 | ss = preprocessing.StandardScaler() 43 | ss.fit(fea_train1) 44 | sc_train = ss.transform(fea_train1) 45 | sc_test = ss.transform(fea_test1) 46 | # x_test_fea = sc_test .reshape(sc_test.shape[0], -1, 12) 47 | 48 | fea_all = np.concatenate([sc_train, sc_test], axis=0) 49 | 50 | # 存储为h5文件 51 | file = h5py.File(root_data + 'DB2/data/stimulus/Fea/DB2_s' + str(j) + 'timefea.h5', 'w') 52 | file.create_dataset('fea_all', data=fea_all.astype('float32')) 53 | file.create_dataset('fea_label', data=label.astype('int')) 54 | file.create_dataset('fea_rep', data=rep.astype('int')) 55 | 56 | file.close() 57 | print('******************DB2_s' + str(j) + '分割完成***********************') -------------------------------------------------------------------------------- /Models/TrainModel/1EmgTrain.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import tensorflow as tf 4 | import h5py 5 | import numpy as np 6 | import nina_funcs as nf 7 | import matplotlib.pyplot as plt 8 | from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau 9 | from tfdeterminism import patch 10 | 11 | 12 | #确定随机数 13 | from Model1D.Away12CNN1D import Away12reluBNCNN1D 14 | from Models.DBEmgNet.Away3CBAMNEW import Away3reluBNCBAMcatNEW 15 | from Models.DBEmgNet.emgFile import reluBNCBAMcat 16 | from Util.SepData import Sep3Data, Sep12Data 17 | from Util.function import get_threeSet 18 | 19 | patch() 20 | np.random.seed(123) 21 | tf.random.set_seed(123) 22 | os.environ["CUDA_VISIBLE_DEVICES"] = "1" 23 | 24 | 25 | 26 | def pltCurve(loss, val_loss, accuracy, val_accuracy): 27 | epochs = range(1, len(loss) + 1) 28 | plt.plot(epochs, loss, label='Training loss') 29 | plt.plot(epochs, val_loss, label='Validation loss') 30 | plt.plot(epochs, accuracy, label='Training accuracy') 31 | plt.plot(epochs, val_accuracy, label='Validation val_accuracy') 32 | plt.title('Training and validation loss') 33 | plt.xlabel('Epochs') 34 | plt.ylabel('Loss') 35 | plt.legend() 36 | plt.show() 37 | 38 | 39 | 40 | root_data = 'D:/Pengxiangdong/ZX/DB2/' 41 | 42 | if __name__ == '__main__': 43 | for j in range(1, 2): 44 | file = h5py.File(root_data+'data/stimulus/Seg/DB2_s' + str(j) + 'Seg.h5', 'r') 45 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 46 | file.close() 47 | 48 | emg_train, emg_vali, emg_test, label_train, label_vail, label_test = get_threeSet(emg, label, rep,6) 49 | Y_train = nf.get_categorical(label_train) 50 | Y_vail = nf.get_categorical(label_vail) 51 | 52 | file.close() 53 | 54 | callbacks = [#1设置学习率衰减,2保存最优模型 55 | # ReduceLROnPlateau(monitor='val_accuracy', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, 56 | # cooldown=0, min_lr=0), 57 | ModelCheckpoint(filepath='D:/Pengxiangdong/ZX/DB2/DB2_model/emgmodel/DB2_s' + str(j) + 'testmodel.h5' 58 | , monitor='val_accuracy', save_best_only=True)] 59 | model =reluBNCBAMcat() 60 | model.summary() 61 | history = model.fit(emg_train, Y_train, epochs=50, verbose=2, batch_size=64 62 | # , callbacks=callbacks) 63 | , validation_data=(emg_vali, Y_vail), callbacks=callbacks) 64 | -------------------------------------------------------------------------------- /Models/DBEmgNet/DownAway3CBAM.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import backend as K 3 | from tensorflow.keras import layers as KL 4 | 5 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 6 | 7 | 8 | 9 | 10 | # 3条支路,每个支路做串行的卷积注意力,在网络层加入标准化,注意顺序,早期网络加入1×1卷积 11 | def DownAway3reluBNCBAM(): 12 | input1 = KL.Input(shape=(20, 8)) 13 | input11 = tf.expand_dims(input=input1, axis=3) 14 | input2 = KL.Input(shape=(20, 2)) 15 | input21 = tf.expand_dims(input=input2, axis=3) 16 | input3 = KL.Input(shape=(20, 2)) 17 | input31 = tf.expand_dims(input=input3, axis=3) 18 | #早期融合网络,加入1×1卷积 19 | c1 = KL.Concatenate(axis=-2)([input11, input21, input31]) 20 | c1 = KL.Conv2D(filters=32, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding='same')(c1) 21 | 22 | 23 | x1 = KL.Conv2D(filters=64, kernel_size=(5, 1), strides=(1, 1), activation='relu', padding='same')(input11) 24 | x1 = KL.BatchNormalization()(x1) 25 | x1 = cbam_time(x1) 26 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), activation='relu', padding='same')(x1) 27 | x1 = KL.BatchNormalization()(x1) 28 | output1 = cbam_acquisition(x1) 29 | 30 | 31 | x2 = KL.Conv2D(filters=64, kernel_size=(5, 1), strides=(1, 1), activation='relu', padding='same')(input21) 32 | x2 = KL.BatchNormalization()(x2) 33 | x2 = cbam_time(x2) 34 | x2 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x2) 35 | x2 = KL.BatchNormalization()(x2) 36 | output2 = cbam_acquisition(x2) 37 | 38 | 39 | x3 = KL.Conv2D(filters=64, kernel_size=(5, 1), strides=(1, 1), activation='relu', padding='same')(input31) 40 | x3 = KL.BatchNormalization()(x3) 41 | x3 = cbam_time(x3) 42 | x3 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x3) 43 | x3 = KL.BatchNormalization()(x3) 44 | output3 = cbam_acquisition(x3) 45 | 46 | 47 | c2 = KL.Concatenate(axis=-2)([output1, output2, output3]) 48 | c = KL.Concatenate(axis=-1)([c1, c2]) 49 | X = KL.GlobalAvgPool2D()(c) 50 | X = KL.Dense(128, activation='relu')(X) 51 | X = KL.Dropout(0.2)(X) 52 | s = KL.Dense(49, activation='softmax')(X) 53 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 54 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 55 | loss='categorical_crossentropy', metrics=['accuracy']) 56 | return model 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Preprocess/Combination.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import numpy as np 4 | import scipy.signal as signal 5 | import nina_funcs as nf 6 | 7 | 8 | train_reps = [1, 3, 4, 6] 9 | test_reps = [2, 5] 10 | gestures = list(range(1, 50)) 11 | 12 | '''对nina_funcs继续扩展的从训练集中划分验证集''' 13 | def dataCombin(data, label, rep_arr, reps): 14 | if reps: 15 | x = [np.where(rep_arr[:] == rep) for rep in reps] 16 | train_indices = np.squeeze(np.concatenate(x, axis=-1)) 17 | train_data = data[train_indices, :] 18 | train_label = label[train_indices] 19 | 20 | return train_data, train_label 21 | 22 | 23 | 24 | if __name__ == '__main__': 25 | for j in range(1, 2): 26 | df = pd.read_hdf('D:/Pengxiangdong/ZX/DB2/data/filter/DB2_s' + str(j) + 'filter.h5', 'df') 27 | 28 | '''滑动窗口分割''' 29 | # df1 = nf.normalise(df.copy(deep=True), train_reps) 30 | # 31 | # df2 = df1.copy(deep=True) 32 | # df2.iloc[:, :12] = df2.iloc[:, :12] 33 | # df3 = df2.astype(np.float32) 34 | # 滑动窗口分割 35 | x_train, y_train, r_train = nf.windowing(df, reps=train_reps, gestures=gestures, win_len=400, win_stride=100) 36 | x_test, y_test, r_test = nf.windowing(df, reps=test_reps, gestures=gestures, win_len=400, win_stride=100) 37 | 38 | 39 | 40 | '''数据集合的划分和组合''' 41 | x_train1, y_train1 = dataCombin(x_train, y_train, r_train, [1]) 42 | x_train3, y_train3 = dataCombin(x_train, y_train, r_train, [3]) 43 | x_train4, y_train4 = dataCombin(x_train, y_train, r_train, [4]) 44 | x_train6, y_train6 = dataCombin(x_train, y_train, r_train, [6]) 45 | 46 | 47 | 48 | # 存储为h5文件 49 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/df_Seg/DB2_s' + str(j) + 'Seg.h5', 'w') 50 | file.create_dataset('x_train1', data=x_train1.astype('float32')) 51 | file.create_dataset('x_train3', data=x_train3.astype('float32')) 52 | file.create_dataset('x_train4', data=x_train4.astype('float32')) 53 | file.create_dataset('x_train6', data=x_train6.astype('float32')) 54 | file.create_dataset('y_train1', data=y_train1.astype('int')) 55 | file.create_dataset('y_train3', data=y_train3.astype('int')) 56 | file.create_dataset('y_train4', data=y_train4.astype('int')) 57 | file.create_dataset('y_train6', data=y_train6.astype('int')) 58 | 59 | file.create_dataset('x_test', data=x_test.astype('float32')) 60 | file.create_dataset('y_test', data=y_test.astype('int')) 61 | file.close() 62 | 63 | print('******************DB2_s' + str(j) + '分割完成***********************') 64 | -------------------------------------------------------------------------------- /feature/FeatureMap.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import math 3 | import pandas as pd 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | import nina_funcs as nf 7 | 8 | train_reps = [1, 3, 4, 6] 9 | test_reps = [2, 5] 10 | gestures = list(range(1, 50)) 11 | image_size = 16 12 | channal = 12 13 | 14 | # Two-dimensional discrete features(using Cartesian Product) 15 | def two_dimension_graph(feature): 16 | feature = feature.reshape((feature.shape[0], -1, channal)) #转换为三维 17 | feature = feature.transpose(0, 2, 1) #交换位置后变为(samples, channel, imagesize) 18 | feature_graph = np.zeros((feature.shape[0], image_size, image_size, channal), dtype='float32') 19 | for i in range(feature.shape[0]): 20 | for j in range(feature.shape[1]): 21 | # Cartesian Product 22 | single_use = feature[i, j, :].reshape(-1, image_size) 23 | single_graph = (single_use. T * single_use) 24 | feature_graph[i, :, :, j] = single_graph 25 | # feature_graph = feature_graph.reshape((feature.shape[0], -1)) 26 | return feature_graph 27 | 28 | '''设置信号投影方式''' 29 | def sigmoid(single_feature): 30 | output_s = 0.5(single_feature) 31 | return output_s 32 | 33 | 34 | for j in range(1, 2): 35 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/down_Fea/DB2_s' + str(j) + 'fea.h5', 'r') 36 | '''step1: 获取特征数组''' 37 | x_train, y_train = file['x_train'][:], file['y_train'][:] 38 | x_test, y_test = file['x_test'][:], file['y_test'][:] 39 | file.close() 40 | 41 | '''step2: 特征图像转换''' 42 | #选择特征组合 43 | X_train_high = (x_train.T[::2]).T 44 | X_train_low = (x_train.T[1::2]).T 45 | X_test_high = (x_test.T[::2]).T 46 | X_test_low = (x_test.T[1::2]).T 47 | 48 | X_train_highimg = two_dimension_graph(X_train_high) 49 | X_train_lowimg = two_dimension_graph(X_train_low) 50 | X_test_highimg = two_dimension_graph(X_test_high) 51 | X_test_lowimg = two_dimension_graph(X_test_low) 52 | 53 | 54 | 55 | 56 | # 存储为h5文件 57 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/featureMap/DB2_s' + str(j) + 'map.h5', 'w') 58 | file.create_dataset('X_train_highimg', data=X_train_highimg.astype('float32')) 59 | file.create_dataset('X_train_lowimg', data=X_train_lowimg.astype('float32')) 60 | file.create_dataset('X_test_highimg', data=X_test_highimg.astype('float32')) 61 | file.create_dataset('X_test_lowimg', data=X_test_lowimg.astype('float32')) 62 | 63 | file.create_dataset('y_train', data=y_train.astype('int32')) 64 | file.create_dataset('y_test', data=y_test.astype('int32')) 65 | file.close() 66 | 67 | print('******************DB2_s' + str(j) + '特征图构建完成***********************') 68 | 69 | -------------------------------------------------------------------------------- /Models/TrainModel/1featureTrain.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import h5py 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | from keras.callbacks import ModelCheckpoint 6 | import nina_funcs as nf 7 | from Models.DBFeaNet.FeaModel import model3 8 | from tfdeterminism import patch 9 | 10 | #确定随机数 11 | from Util.function import get_threeSet 12 | 13 | patch() 14 | np.random.seed(123) 15 | tf.random.set_seed(123) 16 | 17 | 18 | 19 | def pltCurve(loss, val_loss, accuracy, val_accuracy): 20 | epochs = range(1, len(loss) + 1) 21 | plt.plot(epochs, loss, label='Training loss') 22 | plt.plot(epochs, val_loss, label='Validation loss') 23 | plt.plot(epochs, accuracy, label='Training accuracy') 24 | plt.plot(epochs, val_accuracy, label='Validation val_accuracy') 25 | plt.title('Training and validation loss') 26 | plt.xlabel('Epochs') 27 | plt.ylabel('Loss') 28 | plt.legend() 29 | plt.show() 30 | 31 | if __name__ == '__main__': 32 | root_data = 'D:/Pengxiangdong/ZX/' 33 | for j in range(1,2): 34 | feaFile = h5py.File(root_data + 'DB2/data/stimulus/Fea/DB2_s' + str(j) + 'fea.h5', 'r') 35 | # 将六次重复手势分开存储 36 | fea_all, fea_label, fea_rep = feaFile['fea_all'][:], feaFile['fea_label'][:], feaFile['fea_rep'][:] 37 | feaFile.close() 38 | fea_train, fea_vali, fea_test, feay_train, feay_vali, feay_test = get_threeSet(fea_all, fea_label, fea_rep, 6) 39 | 40 | Y_train = nf.get_categorical(feay_train) 41 | Y_vali = nf.get_categorical(feay_vali) 42 | 43 | callbacks = [#1设置学习率衰减,2保存最优模型 44 | # EarlyStopping(monitor='val_accuracy', patience=5), 45 | # ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, 46 | # cooldown=0, min_lr=0), 47 | ModelCheckpoint(filepath='D:/Pengxiangdong/ZX/DB2/DB2_model/DB2_s' + str(j) + 'Fea.h5' 48 | , monitor='val_accuracy', save_best_only=True)] 49 | model = model3() 50 | history = model.fit(fea_train , Y_train, epochs=50, verbose=2, batch_size=64 51 | , validation_data=(fea_vali, Y_vali), callbacks=callbacks) 52 | 53 | # loss= history.history['loss'] 54 | # val_loss = history.history['val_loss'] 55 | # accuracy =history.history['accuracy'] 56 | # val_accuracy =history.history['val_accuracy']32 57 | # pltCurve(loss, val_loss, accuracy, val_accuracy) 58 | #早停机制保存最优模型后,不再另外保存 59 | # model.save('D:/Pengxiangdong/ZX/modelsave/3Channel/Away3CBAMcat/DB2_s'+str(j)+'re25seg400100mZsc.h5') 60 | # tf.keras.utils.plot_model(model, to_file='../ModelPng/Away3reluBNCBAMcatNEW.png', show_shapes=True) 61 | 62 | -------------------------------------------------------------------------------- /feature/GetFeature.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import pandas as pd 3 | import numpy as np 4 | from sklearn import preprocessing 5 | import scipy.signal as signal 6 | import matplotlib.pyplot as plt 7 | import nina_funcs as nf 8 | 9 | from Util.function import get_twoSet 10 | 11 | train_reps = [1, 3, 4, 6] 12 | test_reps = [2, 5] 13 | # gestures = list(range(1,50)) 14 | 15 | def fea_transpose(data): 16 | # 为了便于归一化,对矩阵进行转置 17 | arr_T = np.transpose(np.array(data)) 18 | sc_fea = preprocessing.StandardScaler().fit_transform(arr_T) 19 | arr_fea = np.transpose(sc_fea) 20 | return arr_fea 21 | 22 | root_data = 'D:/Pengxiangdong/ZX/' 23 | if __name__ == '__main__': 24 | for j in range(1, 41): 25 | file = h5py.File(root_data + 'DB2/data/restimulus/reSeg/DB2_s' + str(j) + 'SegEnhance.h5', 'r') 26 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 27 | file.close() 28 | emg_train, emg_test, label_train, label_test = get_twoSet(emg, label, rep) 29 | 30 | '''step2: 选择特征组合和归一化''' 31 | # 选择时域特征组合 32 | features = [nf.wl, nf.ssc, nf.rms, nf.median, nf.iemg, nf.wamp] 33 | # features = [nf.iemg, nf.rms, nf.entropy, nf.kurtosis, nf.zero_cross, nf.mean, nf.median, nf.wl, nf.ssc,nf.wamp] 34 | fea_train1 = nf.feature_extractor(features=features, shape=(emg_train.shape[0], -1), data=emg_train) 35 | fea_test1 = nf.feature_extractor(features=features, shape=(emg_test.shape[0], -1), data=emg_test) 36 | 37 | # 选择频域特征组合 38 | # frequency_features = ["fr", "mnp", "mnf", "mdf", "pkf"] 39 | fea_train2 = nf.frequency_features_extractor(shape=(emg_train.shape[0], -1), data=emg_train) 40 | fea_test2 = nf.frequency_features_extractor(shape=(emg_test.shape[0], -1), data=emg_test) 41 | 42 | fea_train = np.concatenate([fea_train1, fea_train2], axis=-1) 43 | fea_test = np.concatenate([fea_test1, fea_test2], axis=-1) 44 | 45 | 46 | # fea_all = np.concatenate([fea_train, fea_test], axis=0) 47 | 48 | 49 | ss = preprocessing.StandardScaler() 50 | ss.fit(fea_train) 51 | sc_train = ss.transform(fea_train) 52 | sc_test = ss.transform(fea_test) 53 | # # x_test_fea = sc_test .reshape(sc_test.shape[0], -1, 12) 54 | # 55 | sc_all = np.concatenate([sc_train, sc_test], axis=0) 56 | 57 | # 存储为h5文件 58 | file = h5py.File(root_data + 'DB2/data/restimulus/Fea/DB2_s' + str(j) + 'feaEnhance.h5', 'w') 59 | file.create_dataset('fea_all', data=sc_all.astype('float32')) 60 | file.create_dataset('fea_label', data=label.astype('int')) 61 | file.create_dataset('fea_rep', data=rep.astype('int')) 62 | 63 | file.close() 64 | print('******************DB2_s' + str(j) + '分割完成***********************') -------------------------------------------------------------------------------- /Models/TrainModel/1EmgFeaTrain.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import h5py 3 | import numpy as np 4 | import nina_funcs as nf 5 | import matplotlib.pyplot as plt 6 | from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau 7 | from tfdeterminism import patch 8 | from Models.DBFeaEmgNet.FeaEmgFile import FeaAndEmg_se 9 | from Util.function import get_threeSet 10 | #确定随机数 11 | 12 | patch() 13 | np.random.seed(123) 14 | tf.random.set_seed(123) 15 | # os.environ["CUDA_VISIBLE_DEVICES"] = "1" 16 | 17 | 18 | 19 | def pltCurve(loss, val_loss, accuracy, val_accuracy): 20 | epochs = range(1, len(loss) + 1) 21 | plt.plot(epochs, loss, label='Training loss') 22 | plt.plot(epochs, val_loss, label='Validation loss') 23 | plt.plot(epochs, accuracy, label='Training accuracy') 24 | plt.plot(epochs, val_accuracy, label='Validation val_accuracy') 25 | plt.title('Training and validation loss') 26 | plt.xlabel('Epochs') 27 | plt.ylabel('Loss') 28 | plt.legend() 29 | plt.show() 30 | 31 | root_data = 'D:/Pengxiangdong/ZX/' 32 | 33 | if __name__ == '__main__': 34 | for j in range(1, 2): 35 | file = h5py.File(root_data + 'DB2/data/stimulus/TimeSeg/DB2_s' + str(j) + 'Seg.h5', 'r') 36 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 37 | emg_train, emg_vali, emg_test, label_train, label_vail, label_test = get_threeSet(emg, label, rep, 6) 38 | file.close() 39 | Y_train = nf.get_categorical(label_train) 40 | Y_vali = nf.get_categorical(label_vail) 41 | 42 | 43 | 44 | feaFile = h5py.File(root_data + 'DB2/data/stimulus/TimeFea/DB2_s' + str(j) + 'fea.h5', 'r') 45 | # 将六次重复手势分开存储 46 | fea_all, fea_label, fea_rep = feaFile['fea_all'][:], feaFile['fea_label'][:], feaFile['fea_rep'][:] 47 | feaFile.close() 48 | fea_train, fea_vali, fea_test, feay_train, feay_vail, feay_test = get_threeSet(fea_all, fea_label, fea_rep, 6) 49 | 50 | '''特征向量数据适应''' 51 | fea_train = np.expand_dims(fea_train, axis=-1) 52 | fea_vali = np.expand_dims(fea_vali, axis=-1) 53 | 54 | callbacks = [ # 1设置学习率衰减,2保存最优模型 55 | ReduceLROnPlateau(monitor='val_accuracy', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, 56 | cooldown=0, min_lr=0), 57 | ModelCheckpoint(filepath=root_data+'DB2/DB2_model/DB2_s' + str(j) + 'newmodel.h5' 58 | , monitor='val_accuracy', save_best_only=True)] 59 | model = FeaAndEmg_model1() 60 | history = model.fit([emg_train, fea_train], Y_train, epochs=50, verbose=2, batch_size=32 61 | # , callbacks=callbacks) 62 | , validation_data=([emg_vali, fea_vali], Y_vali), callbacks=callbacks) 63 | 64 | -------------------------------------------------------------------------------- /Models/TestModel/1CTestMer1.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | import h5py 3 | from tensorflow import keras 4 | from keras.utils.np_utils import to_categorical 5 | import numpy as np 6 | from sklearn.metrics import confusion_matrix, f1_score, classification_report 7 | import matplotlib.pyplot as plt 8 | 9 | def plot_confusion_matrix(cm, savename, title='Confusion Matrix'): 10 | plt.figure(figsize=(20, 16), dpi=100) 11 | np.set_printoptions(precision=2) # 用于控制Python中小数的显示精度 12 | classes = [] 13 | for i in range(len(cm)): 14 | classes.append(i) 15 | iters = np.reshape([[[i, j] for j in range(len(classes))] for i in range(len(classes))], (cm.size, 2)) 16 | for i, j in iters: 17 | plt.text(j, i, format(cm[i, j])) # 显示对应的数字 18 | xlocations = np.array(range(len(classes))) 19 | plt.xticks(xlocations, classes, rotation=90) 20 | plt.yticks(xlocations, classes) 21 | plt.title(title) 22 | plt.ylabel('Actual label') 23 | plt.xlabel('Predict label') 24 | # show confusion matrix 25 | plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Oranges) 26 | plt.colorbar() 27 | plt.savefig(savename, format='png') 28 | plt.show() 29 | 30 | 31 | # 多分类中每个类别的评价标准 32 | def multiclassEva(cm): 33 | FP = cm.sum(axis=0) - np.diag(cm) 34 | FN = cm.sum(axis=1) - np.diag(cm) 35 | TP = np.diag(cm) 36 | TN = cm.sum() - (FP + FN + TP) 37 | # 返回各个类的TP,TN,FP,FN 得到的数组可以通过np.mean()求整体的均值 38 | Pre = TP / (TP + FP) # 查准率 39 | Recall = TP / (TP + FN) # 查全率 40 | F1score = 2 * [(Pre * Recall) / (Pre + Recall)] 41 | 42 | return Recall, Pre, F1score 43 | 44 | #整体分类的评价结果 45 | def OverallEva(Recall, Pre, F1score): 46 | allRecall = np.mean(Recall) 47 | allF1score = np.mean(F1score) 48 | allPre = np.mean(Pre) 49 | return allRecall, allPre, allF1score 50 | 51 | 52 | 53 | if __name__ == '__main__': 54 | file = h5py.File('../../data/DB2_S1seg400mMinMax.h5', 'r') 55 | X_test = file['testData'][:] 56 | Y_test = file['testLabel'][:] 57 | model = keras.models.load_model('../TrainModel/savemodel/1Cmodel/1C-100E-seg400mMinMax.h5') 58 | Y_test = to_categorical(np.array(Y_test)) 59 | Y_predict = model.predict(X_test) 60 | 61 | # # 返回每行中概率最大的元素的列坐标(热编码转为普通标签) 62 | y_pred = Y_predict.argmax(axis=1) 63 | y_true = Y_test.argmax(axis=1) 64 | 65 | cm = confusion_matrix(y_true, y_pred) 66 | # plot_confusion_matrix(cm,'1C-50E-2e4.png') 67 | classes = [] 68 | for i in range(len(cm)): 69 | classes.append(str(i)) 70 | contexts = classification_report(y_true, y_pred, target_names=classes, digits=4) 71 | with open("1C-100Ebn-seg400mMinMax.txt", "w", encoding='utf-8') as f: 72 | f.write(str(contexts)) 73 | f.close() 74 | # print(classification_report(y_true, y_pred, target_names=classes, digits=4)) 75 | 76 | 77 | -------------------------------------------------------------------------------- /Models/TrainModel/Train3main.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import h5py 3 | import numpy as np 4 | import nina_funcs as nf 5 | import matplotlib.pyplot as plt 6 | from keras.callbacks import ModelCheckpoint 7 | from Models.DBEmgNet.Away3CBAMNEW import Away3reluBNCBAMcatNEW 8 | from Util.SepData import Sep3Data 9 | from tfdeterminism import patch 10 | 11 | 12 | #确定随机数 13 | from Util.function import get_threeSet 14 | 15 | patch() 16 | np.random.seed(123) 17 | tf.random.set_seed(123) 18 | # os.environ["CUDA_VISIBLE_DEVICES"] = "1" 19 | 20 | 21 | 22 | def pltCurve(loss, val_loss, accuracy, val_accuracy): 23 | epochs = range(1, len(loss) + 1) 24 | plt.plot(epochs, loss, label='Training loss') 25 | plt.plot(epochs, val_loss, label='Validation loss') 26 | plt.plot(epochs, accuracy, label='Training accuracy') 27 | plt.plot(epochs, val_accuracy, label='Validation val_accuracy') 28 | plt.title('Training and validation loss') 29 | plt.xlabel('Epochs') 30 | plt.ylabel('Loss') 31 | plt.legend() 32 | plt.show() 33 | 34 | 35 | 36 | if __name__ == '__main__': 37 | for j in range(1,2): 38 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/stimulus/TimeSeg/DB2_s' + str(j) + 'Seg.h5', 'r') 39 | # 数据集划分呢 40 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 41 | file.close() 42 | 43 | emg_train, emg_vali, emg_test, label_train, label_vail, label_test = get_threeSet(emg, label, rep,6) 44 | Y_train = nf.get_categorical(label_train) 45 | Y_vali = nf.get_categorical(label_vail) 46 | 47 | Xtrain1, Xtrain2, Xtrain3 = Sep3Data(emg_train) 48 | Xvali1, Xvali2, Xvali3 = Sep3Data(emg_vali) 49 | 50 | 51 | callbacks = [#1设置学习率衰减,2保存最优模型 52 | # ReduceLROnPlateau(monitor='val_accuracy', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, 53 | # cooldown=0, min_lr=0), 54 | ModelCheckpoint(filepath='D:/Pengxiangdong/ZX/DB2/DB2_model/DB2_s' + str(j) + 'seg.h5' 55 | , monitor='val_accuracy', save_best_only=True)] 56 | model = Away3reluBNCBAMcatNEW() 57 | history = model.fit([Xtrain1, Xtrain2, Xtrain3], Y_train, epochs=50, verbose=2, batch_size=64 58 | ,validation_data=([Xvali1, Xvali2, Xvali3],Y_vali), callbacks=callbacks) 59 | 60 | # loss= history.history['loss'] 61 | # val_loss = history.history['val_loss'] 62 | # accuracy =history.history['accuracy'] 63 | # val_accuracy =history.history['val_accuracy']32 64 | # pltCurve(loss, val_loss, accuracy, val_accuracy) 65 | #早停机制保存最优模型后,不再另外保存 66 | # model.save('D:/Pengxiangdong/ZX/modelsave/3Channel/Away3CBAMcat/DB2_s'+str(j)+'re25seg400100mZsc.h5') 67 | # tf.keras.utils.plot_model(model, to_file='../ModelPng/Away3reluBNCBAMcatNEW.png', show_shapes=True) 68 | 69 | -------------------------------------------------------------------------------- /other/Test1.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | import h5py 3 | from tensorflow import keras 4 | from keras.utils.np_utils import to_categorical 5 | import numpy as np 6 | from sklearn.metrics import confusion_matrix, f1_score, classification_report 7 | import matplotlib.pyplot as plt 8 | 9 | def plot_confusion_matrix(cm, savename, title='Confusion Matrix'): 10 | plt.figure(figsize=(20, 16), dpi=100) 11 | np.set_printoptions(precision=2) # 用于控制Python中小数的显示精度 12 | classes = [] 13 | for i in range(len(cm)): 14 | classes.append(i) 15 | iters = np.reshape([[[i, j] for j in range(len(classes))] for i in range(len(classes))], (cm.size, 2)) 16 | for i, j in iters: 17 | plt.text(j, i, format(cm[i, j])) # 显示对应的数字 18 | xlocations = np.array(range(len(classes))) 19 | plt.xticks(xlocations, classes, rotation=90) 20 | plt.yticks(xlocations, classes) 21 | plt.title(title) 22 | plt.ylabel('Actual label') 23 | plt.xlabel('Predict label') 24 | # show confusion matrix 25 | plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Oranges) 26 | plt.colorbar() 27 | plt.savefig(savename, format='png') 28 | plt.show() 29 | 30 | 31 | # 多分类中每个类别的评价标准 32 | def multiclassEva(cm): 33 | FP = cm.sum(axis=0) - np.diag(cm) 34 | FN = cm.sum(axis=1) - np.diag(cm) 35 | TP = np.diag(cm) 36 | TN = cm.sum() - (FP + FN + TP) 37 | # 返回各个类的TP,TN,FP,FN 得到的数组可以通过np.mean()求整体的均值 38 | Pre = TP / (TP + FP) # 查准率 39 | Recall = TP / (TP + FN) # 查全率 40 | F1score = 2 * [(Pre * Recall) / (Pre + Recall)] 41 | 42 | return Recall, Pre, F1score 43 | 44 | #整体分类的评价结果 45 | def OverallEva(Recall, Pre, F1score): 46 | allRecall = np.mean(Recall) 47 | allF1score = np.mean(F1score) 48 | allPre = np.mean(Pre) 49 | return allRecall, allPre, allF1score 50 | 51 | 52 | 53 | if __name__ == '__main__': 54 | file = h5py.File('../data/DB2_S1segment.h5', 'r') 55 | X_test = file['testData'][:] 56 | Y_test = file['testLabel'][:] 57 | 58 | Y_test = to_categorical(np.array(Y_test)) 59 | model = keras.models.load_model('MutiCnn.h5') 60 | Y_predict = model.predict(X_test) 61 | 62 | # # 返回每行中概率最大的元素的列坐标(热编码转为普通标签) 63 | y_pred = Y_predict.argmax(axis=1) 64 | y_true = Y_test.argmax(axis=1) 65 | 66 | cm = confusion_matrix(y_true, y_pred) 67 | # multiclassEva(cm) 68 | plot_confusion_matrix(cm,'DB2_S1muti.png') 69 | classes = [] 70 | for i in range(len(cm)): 71 | classes.append(str(i)) 72 | # print(f1_score(Y_test.argmax(axis=1), Y_predict.argmax(axis=1), average='weighted')) 73 | # print(f1_score(Y_test.argmax(axis=1), Y_predict.argmax(axis=1), average='micro')) 74 | contexts = classification_report(y_true, y_pred, target_names=classes, digits=4) 75 | with open("cnn.txt", "w", encoding='utf-8') as f: 76 | f.write(str(contexts)) 77 | f.close() 78 | # print(classification_report(y_true, y_pred, target_names=classes, digits=4)) 79 | 80 | 81 | -------------------------------------------------------------------------------- /Models/TrainModel/EnergyTrain.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import h5py 3 | import numpy as np 4 | import nina_funcs as nf 5 | import matplotlib.pyplot as plt 6 | import os 7 | from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau 8 | 9 | from Models.PopularModel.Energy import EnergyCNN 10 | from Util.SepData import Sep3Data 11 | from tfdeterminism import patch 12 | 13 | 14 | #确定随机数 15 | patch() 16 | np.random.seed(123) 17 | tf.random.set_seed(123) 18 | # os.environ["CUDA_VISIBLE_DEVICES"] = "1" 19 | 20 | 21 | 22 | def pltCurve(loss, val_loss, accuracy, val_accuracy): 23 | epochs = range(1, len(loss) + 1) 24 | plt.plot(epochs, loss, label='Training loss') 25 | plt.plot(epochs, val_loss, label='Validation loss') 26 | plt.plot(epochs, accuracy, label='Training accuracy') 27 | plt.plot(epochs, val_accuracy, label='Validation val_accuracy') 28 | plt.title('Training and validation loss') 29 | plt.xlabel('Epochs') 30 | plt.ylabel('Loss') 31 | plt.legend() 32 | plt.show() 33 | 34 | if __name__ == '__main__': 35 | for j in range(1,2): 36 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/energy_map/DB2_s' + str(j) + 'map17.h5', 'r') 37 | # 数据集划分呢 38 | map1, map3, map4, map6 = file['map1'][:], file['map3'][:], file['map4'][:], file['map6'][:] 39 | y_train1, y_train3, y_train4, y_train6 = file['y_train1'][:], file['y_train3'][:], file['y_train4'][:], file['y_train6'][:] 40 | maptest = file['maptest'][:] 41 | y_test = file['y_test'][:] 42 | 43 | file.close() 44 | 45 | X_train = np.concatenate([map1, map3, map4, map6], axis=0) 46 | y_train = np.concatenate([y_train1, y_train3, y_train4, y_train6], axis=0) 47 | 48 | Y_train = nf.get_categorical(y_train) 49 | Y_vali = nf.get_categorical(y_test) 50 | Y_label6 = nf.get_categorical(y_train6) 51 | 52 | callbacks = [#1设置学习率衰减,2保存最优模型 53 | ReduceLROnPlateau(monitor='val_accuracy', factor=0.1, patience=5, mode='auto', min_delta=0.0001, 54 | cooldown=0, min_lr=0), 55 | ModelCheckpoint(filepath='D:/Pengxiangdong/ZX/DB2/DB2_model' 56 | '/DB2_s' + str(j) + 'model.h5' 57 | , monitor='val_accuracy', save_best_only=True)] 58 | model = EnergyCNN() 59 | history = model.fit(X_train, Y_train, epochs=100, verbose=2, batch_size=128 60 | # ,validation_split=0.25,callbacks=callbacks) 61 | ,validation_data=(maptest, Y_vali), callbacks=callbacks) 62 | 63 | # loss= history.history['loss'] 64 | # val_loss = history.history['val_loss'] 65 | # accuracy =history.history['accuracy'] 66 | # val_accuracy =history.history['val_accuracy']32 67 | # pltCurve(loss, val_loss, accuracy, val_accuracy) 68 | #早停机制保存最优模型后,不再另外保存 69 | # model.save('D:/Pengxiangdong/ZX/modelsave/3Channel/Away3CBAMcat/DB2_s'+str(j)+'re25seg400100mZsc.h5') 70 | # tf.keras.utils.plot_model(model, to_file='../ModelPng/Away3reluBNCBAMcatNEW.png', show_shapes=True) 71 | 72 | -------------------------------------------------------------------------------- /Models/DBlayers/SENet.py: -------------------------------------------------------------------------------- 1 | from tensorflow.keras.layers import GlobalAveragePooling2D, Reshape, Dense, multiply 2 | import tensorflow as tf 3 | from tensorflow.keras import backend as K 4 | from tensorflow.keras import layers as KL 5 | 6 | 7 | def se_block(input_feature, ratio=8): 8 | channel_axis = 1 if K.image_data_format() == "channels_first" else -1 9 | channel = input_feature.shape[channel_axis] 10 | 11 | se_feature = GlobalAveragePooling2D()(input_feature) 12 | se_feature = Reshape((1, 1, channel))(se_feature) # 第一步:压缩(Squeeze), reshape成1✖️1✖️C 13 | # assert se_feature._keras_shape[1:] == (1,1,channel) 14 | # 第二步:激励(Excitation), 15 | # 由两个全连接层组成,其中SERatio是一个缩放参数,这个参数的目的是为了减少通道个数从而降低计算量。 16 | # 第一个全连接层有(C/radio)个神经元,输入为1×1×C,输出1×1×(C/radio)。 17 | # 第二个全连接层有C个神经元,输入为1×1×(C/radio),输出为1×1×C。 18 | se_feature = Dense(channel // ratio, 19 | activation='relu', 20 | kernel_initializer='he_normal', 21 | use_bias=True, 22 | bias_initializer='zeros')(se_feature) 23 | # assert se_feature._keras_shape[1:] == (1, 1, channel // ratio) 24 | se_feature = Dense(channel, 25 | activation='sigmoid', 26 | kernel_initializer='he_normal', 27 | use_bias=True, 28 | bias_initializer='zeros')(se_feature) 29 | # assert se_feature._keras_shape[1:] == (1, 1, channel) 30 | """ 31 | # 因为keras默认为channels_last,没修改不需要加这段 32 | if K.image_data_format() == 'channels_first': 33 | se_feature = Permute((3, 1, 2))(se_feature) 34 | """ 35 | se_feature = multiply([input_feature, se_feature]) 36 | return se_feature 37 | 38 | 39 | def SENet_model(): 40 | input1 = KL.Input(shape=(400, 12)) 41 | input11 = tf.expand_dims(input=input1, axis=3) 42 | input2 = KL.Input(shape=(36, 1)) 43 | 44 | # 早期融合网络,加入1×1卷积 45 | x1 = KL.Conv2D(filters=64, kernel_size=(10, 1), strides=(1, 1), activation='relu', padding='same')(input11) 46 | x1 = KL.BatchNormalization()(x1) 47 | x1 = se_block(x1) 48 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x1) 49 | x1 = KL.BatchNormalization()(x1) 50 | x1 = se_block(x1) 51 | x1 = KL.GlobalAvgPool2D()(x1) 52 | 53 | 54 | x2 = KL.Conv1D(filters=64, kernel_size=3, strides=1, activation='relu', padding='valid')(input2) 55 | x2 = KL.MaxPool1D(pool_size=2, strides=1, padding='valid')(x2) 56 | x2 = KL.Conv1D(filters=128, kernel_size=5, strides=1, activation='relu', padding='valid')(x2) 57 | x2 = KL.MaxPool1D(pool_size=2, strides=1, padding='valid')(x2) 58 | x2 = KL.GlobalAvgPool1D()(x2) 59 | 60 | X = KL.Concatenate(axis=-1)([x1, x2]) 61 | X = KL.Dense(256, activation='relu')(X) 62 | X = KL.Dropout(0.2)(X) 63 | s = KL.Dense(49, activation='softmax')(X) 64 | model = tf.keras.Model(inputs=[input1, input2], outputs=s) 65 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 66 | loss='categorical_crossentropy', metrics=['accuracy']) 67 | return model 68 | -------------------------------------------------------------------------------- /Util/confusion_matrix.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | from tensorflow import keras 3 | from keras.utils.np_utils import to_categorical 4 | import numpy as np 5 | from sklearn.metrics import confusion_matrix, f1_score, classification_report 6 | import matplotlib.pyplot as plt 7 | import nina_funcs as nf 8 | from Models.TrainModel import Train3main 9 | 10 | 11 | def plot_confusion_matrix(cm, savename, title='Confusion Matrix'): 12 | plt.figure(figsize=(20, 16), dpi=100) 13 | np.set_printoptions(precision=2) # 用于控制Python中小数的显示精度 14 | classes = [] 15 | for i in range(len(cm)): 16 | classes.append(i) 17 | iters = np.reshape([[[i, j] for j in range(len(classes))] for i in range(len(classes))], (cm.size, 2)) 18 | for i, j in iters: 19 | plt.text(j, i, format(cm[i, j])) # 显示对应的数字 20 | xlocations = np.array(range(len(classes))) 21 | plt.xticks(xlocations, classes, rotation=90) 22 | plt.yticks(xlocations, classes) 23 | plt.title(title) 24 | plt.ylabel('Actual label') 25 | plt.xlabel('Predict label') 26 | # show confusion matrix 27 | plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Oranges) 28 | plt.colorbar() 29 | plt.savefig(savename, format='png') 30 | plt.show() 31 | 32 | 33 | # 多分类中每个类别的评价标准 34 | def multiclassEva(cm): 35 | FP = cm.sum(axis=0) - np.diag(cm) 36 | FN = cm.sum(axis=1) - np.diag(cm) 37 | TP = np.diag(cm) 38 | TN = cm.sum() - (FP + FN + TP) 39 | # 返回各个类的TP,TN,FP,FN 得到的数组可以通过np.mean()求整体的均值 40 | Pre = TP / (TP + FP) # 查准率 41 | Recall = TP / (TP + FN) # 查全率 42 | F1score = 2 * [(Pre * Recall) / (Pre + Recall)] 43 | 44 | return Recall, Pre, F1score 45 | 46 | #整体分类的评价结果 47 | def OverallEva(Recall, Pre, F1score): 48 | allRecall = np.mean(Recall) 49 | allF1score = np.mean(F1score) 50 | allPre = np.mean(Pre) 51 | return allRecall, allPre, allF1score 52 | 53 | 54 | dir = 'D:/Pengxiangdong/ZX/' 55 | 56 | if __name__ == '__main__': 57 | for j in range(1, 2): 58 | file = h5py.File(dir + 'DB2/data/NorSeg/DB2_s' + str(j) + 'Seg.h5', 'r') 59 | # 选定手势做训练集,测试集,验证集 60 | X_test = file['emg_test'][:] 61 | Y_test = file['y_test'][:] 62 | file.close() 63 | 64 | Y_test = nf.get_categorical(Y_test) 65 | model = keras.models.load_model('D:/Pengxiangdong/ZX/DB2/DB2_model' 66 | '/DB2_s' + str(j) + 'model.h5') 67 | 68 | 69 | Y_predict = model.predict(X_test) 70 | 71 | # # 返回每行中概率最大的元素的列坐标(热编码转为普通标签) 72 | y_pred = Y_predict.argmax(axis=1) 73 | y_true = Y_test.argmax(axis=1) 74 | 75 | cm = confusion_matrix(y_true, y_pred) 76 | # plot_confusion_matrix(cm,'1C-50E-2e4.png') 77 | classes = [] 78 | for i in range(len(cm)): 79 | classes.append(str(i)) 80 | contexts = classification_report(y_true, y_pred, target_names=classes, digits=4) 81 | 82 | with open(dir+"DB2/result/111/DB2_s"+str(j)+"6seg.txt", "w", encoding='utf-8') as f: 83 | f.write(str(contexts)) 84 | f.close() 85 | # print(classification_report(y_true, y_pred, target_names=classes, digits=4)) 86 | 87 | 88 | -------------------------------------------------------------------------------- /Model1D/Train1D.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import tensorflow as tf 4 | import h5py 5 | import numpy as np 6 | import nina_funcs as nf 7 | import matplotlib.pyplot as plt 8 | from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau 9 | from tfdeterminism import patch 10 | 11 | 12 | #确定随机数 13 | from Model1D.Away12CNN1D import Away12reluBNCNN1D 14 | from Models.DBEmgNet.Away3CBAMNEW import Away3reluBNCBAMcatNEW 15 | from Models.DBEmgNet.emgFile import reluBNCBAMcat 16 | from Util.SepData import Sep3Data, Sep12Data 17 | from Util.function import get_threeSet 18 | 19 | patch() 20 | np.random.seed(123) 21 | tf.random.set_seed(123) 22 | os.environ["CUDA_VISIBLE_DEVICES"] = "1" 23 | 24 | 25 | 26 | def pltCurve(loss, val_loss, accuracy, val_accuracy): 27 | epochs = range(1, len(loss) + 1) 28 | plt.plot(epochs, loss, label='Training loss') 29 | plt.plot(epochs, val_loss, label='Validation loss') 30 | plt.plot(epochs, accuracy, label='Training accuracy') 31 | plt.plot(epochs, val_accuracy, label='Validation val_accuracy') 32 | plt.title('Training and validation loss') 33 | plt.xlabel('Epochs') 34 | plt.ylabel('Loss') 35 | plt.legend() 36 | plt.show() 37 | 38 | def restore(array): 39 | N1 = 4; 40 | N2 = 100 41 | X = np.zeros([array.shape[0], N1, N2, array.shape[2]]) 42 | for i in range(len(array)): 43 | temp = array[i, :, :] 44 | for j in range(12): 45 | temp2 = temp[:,j].reshape(N1, N2) 46 | X[i, :, :, j] = temp2 47 | 48 | return X 49 | 50 | 51 | root_data = 'D:/Pengxiangdong/ZX/DB2/' 52 | 53 | if __name__ == '__main__': 54 | for j in (1, 26, 38): 55 | file = h5py.File(root_data+'data/stimulus/Seg/DB2_s' + str(j) + 'Seg.h5', 'r') 56 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 57 | file.close() 58 | 59 | emg_train, emg_vali, emg_test, label_train, label_vail, label_test = get_threeSet(emg, label, rep,6) 60 | Y_train = nf.get_categorical(label_train) 61 | Y_vail = nf.get_categorical(label_vail) 62 | 63 | Xtrain1, Xtrain2, Xtrain3,Xtrain4, Xtrain5, Xtrain6,Xtrain7, Xtrain8, Xtrain9,Xtrain10, Xtrain11, Xtrain12 = Sep12Data(emg_train) 64 | Xvali1, Xvali2, Xvali3,Xvali4, Xvali5, Xvali6,Xvali7, Xvali8, Xvali9,Xvali10, Xvali11, Xvali12 = Sep12Data(emg_vali) 65 | file.close() 66 | 67 | callbacks = [#1设置学习率衰减,2保存最优模型 68 | # ReduceLROnPlateau(monitor='val_accuracy', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, 69 | # cooldown=0, min_lr=0), 70 | ModelCheckpoint(filepath='D:/Pengxiangdong/ZX/DB2/DB2_model/DB2_s' + str(j) + 'testmodel.h5' 71 | , monitor='val_accuracy', save_best_only=True)] 72 | model =Away3reluBNCBAMcatNEW() 73 | model.summary() 74 | history = model.fit([Xtrain1, Xtrain2, Xtrain3,Xtrain4, Xtrain5, Xtrain6,Xtrain7, Xtrain8, Xtrain9,Xtrain10, Xtrain11, Xtrain12], Y_train, epochs=50, verbose=2, batch_size=64 75 | , validation_data=([Xvali1, Xvali2, Xvali3,Xvali4, Xvali5, Xvali6,Xvali7, Xvali8, Xvali9,Xvali10, Xvali11, Xvali12], Y_vail), callbacks=callbacks) 76 | -------------------------------------------------------------------------------- /Util/SepData.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | import h5py 3 | import numpy as np 4 | 5 | 6 | #数据集分为十二类 7 | def Sep12Data(data): 8 | data1, data2, data3, data4, data5, data6, data7, data8, data9, data10 \ 9 | , data11, data12 = [], [], [], [], [], [], [], [], [], [], [], [], 10 | 11 | for i in range(len(data)): 12 | data1.append(deepcopy(data[i, :, 0])) 13 | data2.append(deepcopy(data[i, :, 1])) 14 | data3.append(deepcopy(data[i, :, 2])) 15 | data4.append(deepcopy(data[i, :, 3])) 16 | data5.append(deepcopy(data[i, :, 4])) 17 | data6.append(deepcopy(data[i, :, 5])) 18 | data7.append(deepcopy(data[i, :, 6])) 19 | data8.append(deepcopy(data[i, :, 7])) 20 | data9.append(deepcopy(data[i, :, 8])) 21 | data10.append(deepcopy(data[i, :, 9])) 22 | data11.append(deepcopy(data[i, :, 10])) 23 | data12.append(deepcopy(data[i, :, 11])) 24 | 25 | data1 = np.array(data1) 26 | data2 = np.array(data2) 27 | data3 = np.array(data3) 28 | data4 = np.array(data4) 29 | data5 = np.array(data5) 30 | data6 = np.array(data6) 31 | data7 = np.array(data7) 32 | data8 = np.array(data8) 33 | data9 = np.array(data9) 34 | data10 = np.array(data10) 35 | data11 = np.array(data11) 36 | data12 = np.array(data12) 37 | 38 | # 重塑成(sample,1) 39 | data1 = data1.reshape(-1, 400, 1) 40 | data2 = data2.reshape(-1, 400, 1) 41 | data3 = data3.reshape(-1, 400, 1) 42 | data4 = data4.reshape(-1, 400, 1) 43 | data5 = data5.reshape(-1, 400, 1) 44 | data6 = data6.reshape(-1, 400, 1) 45 | data7 = data7.reshape(-1, 400, 1) 46 | data8 = data8.reshape(-1, 400, 1) 47 | data9 = data9.reshape(-1, 400, 1) 48 | data10 = data10.reshape(-1, 400, 1) 49 | data11 = data11.reshape(-1, 400, 1) 50 | data12 = data12.reshape(-1, 400, 1) 51 | 52 | return data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 53 | 54 | 55 | #数据集分为二类 56 | def Sep2Data(data): 57 | data1, data2 = [], [] 58 | for i in range(len(data)): 59 | data1.append((data[i, :, 0:8])) 60 | data2.append((data[i, :, 8:12])) 61 | data1 = np.array(data) 62 | data2 = np.array(data2) 63 | return data1, data2 64 | 65 | #数据集分为三类 66 | def Sep3Data(data): 67 | data1, data2, data3 = [], [], [] 68 | for i in range(len(data)): 69 | data1.append((data[i, :, 0:8])) 70 | data2.append((data[i, :, 8:10])) 71 | data3.append((data[i, :, 10:12])) 72 | data1 = np.array(data1) 73 | data2 = np.array(data2) 74 | data3 = np.array(data3) 75 | 76 | return data1, data2, data3 77 | 78 | 79 | def Sep3Fea(data): 80 | data1, data2, data3 = [], [], [] 81 | for i in range(len(data)): 82 | data1.append((data[i, :, :, 0:8])) 83 | data2.append((data[i, :, :, 8:10])) 84 | data3.append((data[i, :, :, 10:12])) 85 | data1 = np.array(data1) 86 | data2 = np.array(data2) 87 | data3 = np.array(data3) 88 | 89 | return data1, data2, data3 90 | 91 | 92 | 93 | # if __name__ == '__main__': 94 | # file = h5py.File('../data/DB2_S1segment2e4.h5', 'r') 95 | # X_train = file['trainData'][:] 96 | # X_test = file['testData'][:] 97 | # 98 | # Xtrain1, Xtrain2, Xtrain3=Sep3trainData(X_train) 99 | -------------------------------------------------------------------------------- /Models/TrainModel/EnergyAndFeaTrain.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import h5py 3 | import numpy as np 4 | import nina_funcs as nf 5 | import matplotlib.pyplot as plt 6 | import os 7 | from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau 8 | 9 | from tfdeterminism import patch 10 | 11 | 12 | #确定随机数 13 | from Models.PopularModel.EnergyAndEmg import EnergyAndEmgCNN, EnergyAndEmgsoft 14 | 15 | patch() 16 | np.random.seed(123) 17 | tf.random.set_seed(123) 18 | # os.environ["CUDA_VISIBLE_DEVICES"] = "1" 19 | 20 | 21 | 22 | def pltCurve(loss, val_loss, accuracy, val_accuracy): 23 | epochs = range(1, len(loss) + 1) 24 | plt.plot(epochs, loss, label='Training loss') 25 | plt.plot(epochs, val_loss, label='Validation loss') 26 | plt.plot(epochs, accuracy, label='Training accuracy') 27 | plt.plot(epochs, val_accuracy, label='Validation val_accuracy') 28 | plt.title('Training and validation loss') 29 | plt.xlabel('Epochs') 30 | plt.ylabel('Loss') 31 | plt.legend() 32 | plt.show() 33 | 34 | if __name__ == '__main__': 35 | for j in range(1,2): 36 | file_emg = h5py.File('D:/Pengxiangdong/ZX/DB2/data/df_Seg/DB2_s' + str(j) + 'Seg.h5', 'r') 37 | emg1, emg3, emg4, emg6 = file_emg['x_train1'][:], file_emg['x_train3'][:]\ 38 | , file_emg['x_train4'][:], file_emg['x_train6'][:] 39 | 40 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/energy_map/DB2_s' + str(j) + 'map.h5', 'r') 41 | # 数据集划分呢 42 | map1, map3, map4, map6 = file['map1'][:], file['map3'][:], file['map4'][:], file['map6'][:] 43 | y_train1, y_train3, y_train4, y_train6 = file['y_train1'][:], file['y_train3'][:], file['y_train4'][:], file['y_train6'][:] 44 | maptest = file['maptest'][:] 45 | y_test = file['y_test'][:] 46 | 47 | 48 | X_train = np.concatenate([emg1, emg3, emg4, emg6], axis=0) 49 | map_train = np.concatenate([map1, map3, map4, map6], axis=0) 50 | y_train = np.concatenate([y_train1, y_train3, y_train4, y_train6], axis=0) 51 | Y_train = nf.get_categorical(y_train) 52 | 53 | X_test = file_emg['x_test'][:] 54 | Y_test = nf.get_categorical(y_test) 55 | file_emg.close() 56 | file.close() 57 | print() 58 | 59 | callbacks = [#1设置学习率衰减,2保存最优模型 60 | # ReduceLROnPlateau(monitor='val_accuracy', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, 61 | # cooldown=0, min_lr=0), 62 | ModelCheckpoint(filepath='D:/Pengxiangdong/ZX/DB2/DB2_model' 63 | '/DB2_s' + str(j) + 'model.h5' 64 | , monitor='val_accuracy', save_best_only=True)] 65 | model = EnergyAndEmgsoft() 66 | history = model.fit([map_train,X_train], Y_train, epochs=100, verbose=2, batch_size=64 67 | ,validation_data=([maptest,X_test],Y_test) 68 | , callbacks=callbacks) 69 | 70 | # loss= history.history['loss'] 71 | # val_loss = history.history['val_loss'] 72 | # accuracy =history.history['accuracy'] 73 | # val_accuracy =history.history['val_accuracy']32 74 | # pltCurve(loss, val_loss, accuracy, val_accuracy) 75 | #早停机制保存最优模型后,不再另外保存 76 | # model.save('D:/Pengxiangdong/ZX/modelsave/3Channel/Away3CBAMcat/DB2_s'+str(j)+'re25seg400100mZsc.h5') 77 | # tf.keras.utils.plot_model(model, to_file='../ModelPng/Away3reluBNCBAMcatNEW.png', show_shapes=True) 78 | 79 | -------------------------------------------------------------------------------- /Models/TestModel/3CTest.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | import h5py 3 | from tensorflow import keras 4 | from keras.utils.np_utils import to_categorical 5 | import numpy as np 6 | from sklearn.metrics import confusion_matrix, f1_score, classification_report 7 | import matplotlib.pyplot as plt 8 | from Models.TrainModel import Train3main 9 | 10 | from Util.SepData import Sep3Data 11 | from Util.function import get_twoSet 12 | import nina_funcs as nf 13 | from Models.DBlayers.CBAM import cbam_acquisition, cbam_time 14 | 15 | 16 | 17 | def plot_confusion_matrix(cm, savename, title='Confusion Matrix'): 18 | plt.figure(figsize=(20, 16), dpi=100) 19 | np.set_printoptions(precision=2) # 用于控制Python中小数的显示精度 20 | classes = [] 21 | for i in range(len(cm)): 22 | classes.append(i) 23 | iters = np.reshape([[[i, j] for j in range(len(classes))] for i in range(len(classes))], (cm.size, 2)) 24 | for i, j in iters: 25 | plt.text(j, i, format(cm[i, j])) # 显示对应的数字 26 | xlocations = np.array(range(len(classes))) 27 | plt.xticks(xlocations, classes, rotation=90) 28 | plt.yticks(xlocations, classes) 29 | plt.title(title) 30 | plt.ylabel('Actual label') 31 | plt.xlabel('Predict label') 32 | # show confusion matrix 33 | plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Oranges) 34 | plt.colorbar() 35 | plt.savefig(savename, format='png') 36 | plt.show() 37 | 38 | 39 | # 多分类中每个类别的评价标准 40 | def multiclassEva(cm): 41 | FP = cm.sum(axis=0) - np.diag(cm) 42 | FN = cm.sum(axis=1) - np.diag(cm) 43 | TP = np.diag(cm) 44 | TN = cm.sum() - (FP + FN + TP) 45 | # 返回各个类的TP,TN,FP,FN 得到的数组可以通过np.mean()求整体的均值 46 | Pre = TP / (TP + FP) # 查准率 47 | Recall = TP / (TP + FN) # 查全率 48 | F1score = 2 * [(Pre * Recall) / (Pre + Recall)] 49 | 50 | return Recall, Pre, F1score 51 | 52 | #整体分类的评价结果 53 | def OverallEva(Recall, Pre, F1score): 54 | allRecall = np.mean(Recall) 55 | allF1score = np.mean(F1score) 56 | allPre = np.mean(Pre) 57 | return allRecall, allPre, allF1score 58 | 59 | 60 | root_data = 'D:/Pengxiangdong/ZX/DB2/' 61 | 62 | if __name__ == '__main__': 63 | for j in range(1, 2): 64 | file = h5py.File(root_data+'data/stimulus/Seg/DB2_s' + str(j) + 'Seg.h5', 'r') 65 | 66 | emg, label, rep = file['emg'][:], file['label'][:], file['rep'][:] 67 | file.close() 68 | 69 | emg_train, emg_test, label_train, label_test = get_twoSet(emg, label, rep) 70 | 71 | Xtest1, Xtest2, Xtest3 = Sep3Data(emg_test) 72 | 73 | model = keras.models.load_model('D:/Pengxiangdong/ZX/DB2/DB2_model/DB2_s' + str(j) + 'threemodel.h5') 74 | 75 | Y_test = nf.get_categorical(np.array(label_test)) 76 | Y_predict = model.predict([Xtest1,Xtest2,Xtest3]) 77 | 78 | # # 返回每行中概率最大的元素的列坐标(热编码转为普通标签) 79 | y_pred = Y_predict.argmax(axis=1) 80 | y_true = Y_test.argmax(axis=1) 81 | 82 | cm = confusion_matrix(y_true, y_pred) 83 | # plot_confusion_matrix(cm,'1C-50E-2e4.png') 84 | classes = [] 85 | for i in range(len(cm)): 86 | classes.append(str(i)) 87 | contexts = classification_report(y_true, y_pred, target_names=classes, digits=4) 88 | 89 | with open("D:/Pengxiangdong/ZX/DB2/result/stimulus/111/DB2_s"+str(j)+"seg6.txt", "w", encoding='utf-8') as f: 90 | f.write(str(contexts)) 91 | f.close() 92 | # print(classification_report(y_true, y_pred, target_names=classes, digits=4)) 93 | 94 | 95 | -------------------------------------------------------------------------------- /Models/DBlayers/Attention.py: -------------------------------------------------------------------------------- 1 | from tensorflow.keras.layers import Activation, Conv2D 2 | import tensorflow.keras.backend as K 3 | import tensorflow as tf 4 | from tensorflow.keras.layers import Layer 5 | 6 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 7 | 8 | class PAM(Layer): 9 | def __init__(self, 10 | gamma_initializer=tf.zeros_initializer(), 11 | gamma_regularizer=None, 12 | gamma_constraint=None, 13 | **kwargs): 14 | super(PAM, self).__init__(**kwargs) 15 | self.gamma_initializer = gamma_initializer 16 | self.gamma_regularizer = gamma_regularizer 17 | self.gamma_constraint = gamma_constraint 18 | 19 | def build(self, input_shape): 20 | self.gamma = self.add_weight(shape=(1, ), 21 | initializer=self.gamma_initializer, 22 | name='gamma', 23 | regularizer=self.gamma_regularizer, 24 | constraint=self.gamma_constraint) 25 | 26 | self.built = True 27 | 28 | def compute_output_shape(self, input_shape): 29 | return input_shape 30 | 31 | def call(self, input): 32 | input_shape = input.get_shape().as_list() 33 | _, h, w, filters = input_shape 34 | 35 | b = Conv2D(filters // 8, 1, use_bias=False, kernel_initializer='he_normal')(input) 36 | c = Conv2D(filters // 8, 1, use_bias=False, kernel_initializer='he_normal')(input) 37 | d = Conv2D(filters, 1, use_bias=False, kernel_initializer='he_normal')(input) 38 | 39 | vec_b = K.reshape(b, (-1, h * w, filters // 8)) 40 | vec_cT = tf.transpose(K.reshape(c, (-1, h * w, filters // 8)), (0, 2, 1)) 41 | bcT = K.batch_dot(vec_b, vec_cT) 42 | softmax_bcT = Activation('softmax')(bcT) 43 | vec_d = K.reshape(d, (-1, h * w, filters)) 44 | bcTd = K.batch_dot(softmax_bcT, vec_d) 45 | bcTd = K.reshape(bcTd, (-1, h, w, filters)) 46 | 47 | out = self.gamma*bcTd + input 48 | return out 49 | 50 | 51 | class CAM(Layer): 52 | def __init__(self, 53 | gamma_initializer=tf.zeros_initializer(), 54 | gamma_regularizer=None, 55 | gamma_constraint=None, 56 | **kwargs): 57 | super(CAM, self).__init__(**kwargs) 58 | self.gamma_initializer = gamma_initializer 59 | self.gamma_regularizer = gamma_regularizer 60 | self.gamma_constraint = gamma_constraint 61 | 62 | def build(self, input_shape): 63 | self.gamma = self.add_weight(shape=(1, ), 64 | initializer=self.gamma_initializer, 65 | name='gamma', 66 | regularizer=self.gamma_regularizer, 67 | constraint=self.gamma_constraint) 68 | 69 | self.built = True 70 | 71 | def compute_output_shape(self, input_shape): 72 | return input_shape 73 | 74 | def call(self, input): 75 | input_shape = input.get_shape().as_list() 76 | _, h, w, filters = input_shape 77 | 78 | vec_a = K.reshape(input, (-1, h * w, filters)) 79 | vec_aT = tf.transpose(vec_a, (0, 2, 1)) 80 | aTa = K.batch_dot(vec_aT, vec_a) 81 | softmax_aTa = Activation('softmax')(aTa) 82 | aaTa = K.batch_dot(vec_a, softmax_aTa) 83 | aaTa = K.reshape(aaTa, (-1, h, w, filters)) 84 | 85 | out = self.gamma*aaTa + input 86 | return out -------------------------------------------------------------------------------- /Models/DBlayers/Unet.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import Model,Input 3 | from tensorflow.keras.layers import Permute, Activation, Reshape 4 | from tensorflow.keras.optimizers import Adam 5 | from tensorflow.keras.layers import Bidirectional, Conv2D, MaxPooling2D, Flatten, concatenate, Dropout, \ 6 | Dense, LSTM, UpSampling2D 7 | 8 | 9 | # !/usr/bin/env python 10 | # -*- coding:utf-8 -*- 11 | # Author:CaoZhihui 12 | ... 13 | 14 | 15 | # --Build a net work-- # 16 | def get_net(): 17 | C = 1 18 | img_h = 400 19 | img_w = 400 20 | inputs = Input(shape=(img_h, img_w, C)) 21 | # inputs = tf.expand_dims(input=I_input, axis=3) 22 | # Block 1 23 | conv1 = Conv2D(32, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(inputs) 24 | conv1 = Conv2D(32, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv1) 25 | pool1 = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(conv1) 26 | 27 | # Block 2 28 | conv2 = Conv2D(64, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(pool1) 29 | conv2 = Conv2D(64, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv2) 30 | pool2 = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(conv2) 31 | 32 | # Block 3 33 | conv3 = Conv2D(128, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(pool2) 34 | conv3 = Conv2D(128, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv3) 35 | pool3 = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(conv3) 36 | 37 | # Block 4 38 | conv4 = Conv2D(256, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(pool3) 39 | conv4 = Conv2D(256, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv4) 40 | pool4 = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(conv4) 41 | 42 | # Block 5 43 | conv5 = Conv2D(512, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(pool4) 44 | conv5 = Conv2D(512, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv5) 45 | 46 | up6 = concatenate([UpSampling2D(size=(2, 2))(conv5), conv4], axis=-1) 47 | conv6 = Conv2D(256, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(up6) 48 | conv6 = Conv2D(256, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv6) 49 | 50 | up7 = concatenate([UpSampling2D(size=(2, 2))(conv6), conv3], axis=-1) 51 | conv7 = Conv2D(128, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(up7) 52 | conv7 = Conv2D(128, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv7) 53 | 54 | up8 = concatenate([UpSampling2D(size=(2, 2))(conv7), conv2], axis=-1) 55 | conv8 = Conv2D(64, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(up8) 56 | conv8 = Conv2D(64, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(conv8) 57 | 58 | up9 = concatenate([UpSampling2D(size=(2, 2))(conv8), conv1], axis=-1) 59 | conv9 = Conv2D(32, (3, 3), activation='relu', padding='same', kernel_initializer='he_normal')(up9) 60 | 61 | conv10 = Conv2D(C, (1, 1), activation='relu', kernel_initializer='he_normal')(conv9) 62 | 63 | X = Dense(1024, activation='relu')(conv10) 64 | X = Dropout(0.5)(X) 65 | outputs = Dense(49, activation='softmax')(X) 66 | 67 | model = Model(inputs=inputs, outputs=outputs) 68 | 69 | model.compile(optimizer=Adam(lr=1.0e-4), loss='categorical_crossentropy', metrics=['accuracy']) 70 | 71 | return model 72 | -------------------------------------------------------------------------------- /Model1D/Test1D.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | import h5py 3 | from tensorflow import keras 4 | from keras.utils.np_utils import to_categorical 5 | import numpy as np 6 | from sklearn.metrics import confusion_matrix, f1_score, classification_report 7 | import matplotlib.pyplot as plt 8 | from Models.TrainModel import Train3main 9 | from Util.SepData import Sep3Data, Sep12Data 10 | 11 | 12 | def plot_confusion_matrix(cm, savename, title='Confusion Matrix'): 13 | plt.figure(figsize=(20, 16), dpi=100) 14 | np.set_printoptions(precision=2) # 用于控制Python中小数的显示精度 15 | classes = [] 16 | for i in range(len(cm)): 17 | classes.append(i) 18 | iters = np.reshape([[[i, j] for j in range(len(classes))] for i in range(len(classes))], (cm.size, 2)) 19 | for i, j in iters: 20 | plt.text(j, i, format(cm[i, j])) # 显示对应的数字 21 | xlocations = np.array(range(len(classes))) 22 | plt.xticks(xlocations, classes, rotation=90) 23 | plt.yticks(xlocations, classes) 24 | plt.title(title) 25 | plt.ylabel('Actual label') 26 | plt.xlabel('Predict label') 27 | # show confusion matrix 28 | plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Oranges) 29 | plt.colorbar() 30 | plt.savefig(savename, format='png') 31 | plt.show() 32 | 33 | 34 | # 多分类中每个类别的评价标准 35 | def multiclassEva(cm): 36 | FP = cm.sum(axis=0) - np.diag(cm) 37 | FN = cm.sum(axis=1) - np.diag(cm) 38 | TP = np.diag(cm) 39 | TN = cm.sum() - (FP + FN + TP) 40 | # 返回各个类的TP,TN,FP,FN 得到的数组可以通过np.mean()求整体的均值 41 | Pre = TP / (TP + FP) # 查准率 42 | Recall = TP / (TP + FN) # 查全率 43 | F1score = 2 * [(Pre * Recall) / (Pre + Recall)] 44 | 45 | return Recall, Pre, F1score 46 | 47 | #整体分类的评价结果 48 | def OverallEva(Recall, Pre, F1score): 49 | allRecall = np.mean(Recall) 50 | allF1score = np.mean(F1score) 51 | allPre = np.mean(Pre) 52 | return allRecall, allPre, allF1score 53 | 54 | 55 | 56 | if __name__ == '__main__': 57 | for j in range(1, 2): 58 | file = h5py.File('F:/DB2/DownSegZsc/DB2_s' + str(j) + 'allDownZsc.h5', 'r') 59 | 60 | Data0, Data1, Data2, Data3, Data4, Data5 = file['Data0'][:], file['Data1'][:], file['Data2'][:] \ 61 | , file['Data3'][:], file['Data4'][:], file['Data5'][:] 62 | Label0, Label1, Label2, Label3, Label4, Label5 = file['label0'][:], file['label1'][:], file['label2'][:] \ 63 | , file['label3'][:], file['label4'][:], file['label5'][:] 64 | file.close() 65 | # 选定手势做训练集,测试集,验证集 66 | # X_test=Data4 67 | # Y_test=Data4 68 | 69 | X_test = np.concatenate([Data1, Data4], axis=0) 70 | Y_test = np.concatenate([Label1, Label4], axis=0) 71 | 72 | Xtest1, Xtest2, Xtest3,Xtest4, Xtest5, Xtest6,Xtest7, Xtest8, Xtest9,Xtest10, Xtest11, Xtest12 = Sep12Data(X_test) 73 | 74 | model = keras.models.load_model('F:/DB2/model/DownAway12reluBNCNN1D/111' 75 | '/DB2_s'+ str(j) + '6seg205mZsc.h5') 76 | 77 | Y_test = to_categorical(np.array(Y_test)) 78 | Y_predict = model.predict([Xtest1, Xtest2, Xtest3,Xtest4, Xtest5, Xtest6,Xtest7, Xtest8, Xtest9,Xtest10, Xtest11, Xtest12]) 79 | 80 | # # 返回每行中概率最大的元素的列坐标(热编码转为普通标签) 81 | y_pred = Y_predict.argmax(axis=1) 82 | y_true = Y_test.argmax(axis=1) 83 | 84 | cm = confusion_matrix(y_true, y_pred) 85 | # plot_confusion_matrix(cm,'1C-50E-2e4.png') 86 | classes = [] 87 | for i in range(len(cm)): 88 | classes.append(str(i)) 89 | contexts = classification_report(y_true, y_pred, target_names=classes, digits=4) 90 | 91 | with open("F:/DB2/result/111/DB2_s"+str(j)+"6seg205mZsc.txt", "w", encoding='utf-8') as f: 92 | f.write(str(contexts)) 93 | f.close() 94 | # print(classification_report(y_true, y_pred, target_names=classes, digits=4)) 95 | 96 | 97 | -------------------------------------------------------------------------------- /Models/PopularModel/Energy.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import backend as K 3 | from tensorflow.keras import layers as KL 4 | from tensorflow.keras import * 5 | 6 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 7 | 8 | 9 | # CAM 特征通道注意力 10 | def channel_attention(input_xs, reduction_ratio=0.125): 11 | # get channel 12 | channel = int(input_xs.shape[channel_axis]) 13 | maxpool_channel = KL.GlobalMaxPooling2D()(input_xs) 14 | maxpool_channel = KL.Reshape((1, 1, channel))(maxpool_channel) 15 | avgpool_channel = KL.GlobalAvgPool2D()(input_xs) 16 | avgpool_channel = KL.Reshape((1, 1, channel))(avgpool_channel) 17 | Dense_One = KL.Dense(units=int(channel * reduction_ratio), activation='relu', kernel_initializer='he_normal', 18 | use_bias=True, bias_initializer='zeros') 19 | Dense_Two = KL.Dense(units=int(channel), activation='relu', kernel_initializer='he_normal', use_bias=True, 20 | bias_initializer='zeros') 21 | # max path 22 | mlp_1_max = Dense_One(maxpool_channel) 23 | mlp_2_max = Dense_Two(mlp_1_max) 24 | mlp_2_max = KL.Reshape(target_shape=(1, 1, int(channel)))(mlp_2_max) 25 | # avg path 26 | mlp_1_avg = Dense_One(avgpool_channel) 27 | mlp_2_avg = Dense_Two(mlp_1_avg) 28 | mlp_2_avg = KL.Reshape(target_shape=(1, 1, int(channel)))(mlp_2_avg) 29 | channel_attention_feature = KL.Add()([mlp_2_max, mlp_2_avg]) 30 | channel_attention_feature = KL.Activation('sigmoid')(channel_attention_feature) 31 | return KL.Multiply()([channel_attention_feature, input_xs]) 32 | 33 | 34 | # SAM 空间注意力 35 | def spatial_attention(channel_refined_feature): 36 | maxpool_spatial = KL.Lambda(lambda x: K.max(x, axis=3, keepdims=True))(channel_refined_feature) 37 | avgpool_spatial = KL.Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(channel_refined_feature) 38 | max_avg_pool_spatial = KL.Concatenate(axis=3)([maxpool_spatial, avgpool_spatial]) 39 | return KL.Conv2D(filters=1, kernel_size=(2, 2), padding="same", activation='sigmoid', 40 | kernel_initializer='he_normal', use_bias=False)(max_avg_pool_spatial) 41 | 42 | 43 | ''' 44 | # 标准的CBAM,没有卷积!!!加入ResBlock''' 45 | def cbam_module(input_xs, reduction_ratio=0.5): 46 | channel_refined_feature = channel_attention(input_xs, reduction_ratio=reduction_ratio) 47 | spatial_attention_feature = spatial_attention(channel_refined_feature) 48 | refined_feature = KL.Multiply()([channel_refined_feature, spatial_attention_feature]) 49 | return KL.Add()([refined_feature, input_xs]) 50 | 51 | 52 | 53 | 54 | # 3条支路,每个支路做串行的卷积注意力,在网络层加入标准化,注意顺序,早期网络加入1×1卷积 55 | def EnergyCNN(): 56 | input1 = KL.Input(shape=(60, 80)) 57 | input11 = tf.expand_dims(input=input1, axis=3) 58 | input11 = KL.BatchNormalization()(input11) 59 | 60 | 61 | #早期融合网络,加入1×1卷积 62 | x1 = KL.Conv2D(filters=16, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same',kernel_regularizer=regularizers.l1(0.01))(input11) 63 | x1 = KL.MaxPool2D(pool_size=(2, 2), strides=(1, 1), padding='same')(x1) 64 | x1 = KL.Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same',kernel_regularizer=regularizers.l1(0.01))(x1) 65 | x1 = KL.MaxPool2D(pool_size=(2, 2), strides=(1,1), padding='same')(x1) 66 | x1 = KL.Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same',kernel_regularizer=regularizers.l1(0.01))(x1) 67 | x1 = KL.MaxPool2D(pool_size=(2, 2), strides=(1, 1), padding='same')(x1) 68 | # x1 = cbam_module(x1) 69 | # x1 = KL.Conv1D(filters=64, kernel_size=20, strides=20, activation='relu', padding='valid')(input1) 70 | # x1 = KL.MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='same')(x1) 71 | # x1 = KL.Conv2D(filters=128, kernel_size=(5, 5), strides=(1, 1), activation='relu', padding='valid')(x1) 72 | # x1 = KL.MaxPool2D(pool_size=(2, 2), strides=(2, 2), padding='same')(x1) 73 | 74 | c = KL.Flatten()(x1) 75 | X = KL.Dense(128, activation='relu')(c) 76 | X = KL.Dropout(0.5)(X) 77 | s = KL.Dense(17, activation='softmax')(X) 78 | model = tf.keras.Model(inputs=input1, outputs=s) 79 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 80 | loss='categorical_crossentropy', metrics=['accuracy']) 81 | return model 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /Models/DBlayers/CBAM.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import regularizers 3 | from tensorflow.keras import backend as K 4 | from tensorflow.keras import layers as KL 5 | 6 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 7 | 8 | 9 | # CAM 特征通道注意力 10 | def channel_attention(input_xs, reduction_ratio=0.125): 11 | # get channel 12 | channel = int(input_xs.shape[channel_axis]) 13 | maxpool_channel = KL.GlobalMaxPooling2D()(input_xs) 14 | maxpool_channel = KL.Reshape((1, 1, channel))(maxpool_channel) 15 | avgpool_channel = KL.GlobalAvgPool2D()(input_xs) 16 | avgpool_channel = KL.Reshape((1, 1, channel))(avgpool_channel) 17 | Dense_One = KL.Dense(units=int(channel * reduction_ratio), activation='relu', kernel_initializer='he_normal', 18 | use_bias=True, bias_initializer='zeros') 19 | Dense_Two = KL.Dense(units=int(channel), activation='relu', kernel_initializer='he_normal', use_bias=True, 20 | bias_initializer='zeros') 21 | # max path 22 | mlp_1_max = Dense_One(maxpool_channel) 23 | mlp_2_max = Dense_Two(mlp_1_max) 24 | mlp_2_max = KL.Reshape(target_shape=(1, 1, int(channel)))(mlp_2_max) 25 | # avg path 26 | mlp_1_avg = Dense_One(avgpool_channel) 27 | mlp_2_avg = Dense_Two(mlp_1_avg) 28 | mlp_2_avg = KL.Reshape(target_shape=(1, 1, int(channel)))(mlp_2_avg) 29 | channel_attention_feature = KL.Add()([mlp_2_max, mlp_2_avg]) 30 | channel_attention_feature = KL.Activation('sigmoid')(channel_attention_feature) 31 | return KL.Multiply()([channel_attention_feature, input_xs]) 32 | 33 | 34 | # SAM 空间注意力 35 | def spatial_attention(channel_refined_feature): 36 | maxpool_spatial = KL.Lambda(lambda x: K.max(x, axis=3, keepdims=True))(channel_refined_feature) 37 | avgpool_spatial = KL.Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(channel_refined_feature) 38 | max_avg_pool_spatial = KL.Concatenate(axis=3)([maxpool_spatial, avgpool_spatial]) 39 | return KL.Conv2D(filters=1, kernel_size=(2, 2), padding="same", activation='sigmoid', 40 | kernel_initializer='he_normal', use_bias=False)(max_avg_pool_spatial) 41 | 42 | # 时间注意力 43 | def time_attention(channel_refined_feature): 44 | maxpool_spatial = KL.Lambda(lambda x: K.max(x, axis=3, keepdims=True))(channel_refined_feature) 45 | avgpool_spatial = KL.Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(channel_refined_feature) 46 | max_avg_pool_spatial = KL.Concatenate(axis=3)([maxpool_spatial, avgpool_spatial]) 47 | return KL.Conv2D(filters=1, kernel_size=(2, 1), padding="same", activation='sigmoid', 48 | kernel_initializer='he_normal', use_bias=False)(max_avg_pool_spatial) 49 | 50 | 51 | # Acquisition channel 采集通道注意力 52 | def acquisition_attention(channel_refined_feature): 53 | maxpool_spatial = KL.Lambda(lambda x: K.max(x, axis=3, keepdims=True))(channel_refined_feature) 54 | avgpool_spatial = KL.Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(channel_refined_feature) 55 | max_avg_pool_spatial = KL.Concatenate(axis=3)([maxpool_spatial, avgpool_spatial]) 56 | return KL.Conv2D(filters=1, kernel_size=(1, 2), padding="same", activation='sigmoid', 57 | kernel_initializer='he_normal', use_bias=False)(max_avg_pool_spatial) 58 | 59 | ''' 60 | # 标准的CBAM,没有卷积!!!加入ResBlock 61 | def cbam_module(input_xs, reduction_ratio=0.5): 62 | channel_refined_feature = channel_attention(input_xs, reduction_ratio=reduction_ratio) 63 | spatial_attention_feature = spatial_attention(channel_refined_feature) 64 | refined_feature = KL.Multiply()([channel_refined_feature, spatial_attention_feature]) 65 | return KL.Add()([refined_feature, input_xs]) 66 | ''' 67 | 68 | 69 | # 加入ResBlock 采集通道注意力机制 70 | def cbam_acquisition(input_xs, reduction_ratio=0.5): 71 | channel_refined_feature = channel_attention(input_xs, reduction_ratio=reduction_ratio) 72 | acquisition_attention_feature = acquisition_attention(channel_refined_feature) 73 | refined_feature = KL.Multiply()([channel_refined_feature, acquisition_attention_feature]) 74 | return KL.Add()([refined_feature, input_xs]) 75 | 76 | # 标准的CBAM,没有卷积!!!加入ResBlock 77 | def cbam_time(input_xs, reduction_ratio=0.5): 78 | channel_refined_feature = channel_attention(input_xs, reduction_ratio=reduction_ratio) 79 | time_attention_feature = time_attention(channel_refined_feature) 80 | refined_feature = KL.Multiply()([channel_refined_feature, time_attention_feature]) 81 | return KL.Add()([refined_feature, input_xs]) 82 | 83 | -------------------------------------------------------------------------------- /Models/PopularModel/EnergyAndEmg.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import tensorflow as tf 3 | from tensorflow.keras import backend as K 4 | from tensorflow.keras import layers as KL 5 | 6 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 7 | 8 | 9 | # 特征级融合测试 10 | def EnergyAndEmgCNN(): 11 | input1 = KL.Input(shape=(60, 80)) 12 | input11 = tf.expand_dims(input=input1, axis=3) 13 | input2 = KL.Input(shape=(400, 12)) 14 | input21 = tf.expand_dims(input=input2, axis=3) 15 | 16 | #早期融合网络,加入1×1卷积 17 | 18 | x1 = KL.Conv2D(filters=64, kernel_size=(4, 4), strides=(1, 1), padding='same')(input11) 19 | x1 = KL.BatchNormalization()(x1) 20 | x1 = KL.Activation('relu')(x1) 21 | x1 = KL.Conv2D(filters=64, kernel_size=(4, 4), strides=(1, 1), padding='same')(x1) 22 | x1 = KL.BatchNormalization()(x1) 23 | x1 = KL.Activation('relu')(x1) 24 | x1 = KL.LocallyConnected2D(64,kernel_size=(2,2))(x1) 25 | x1 = KL.BatchNormalization()(x1) 26 | x1 = KL.Activation('relu')(x1) 27 | f1 = KL.Flatten()(x1) 28 | 29 | 30 | x2 = KL.Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same')(input21) 31 | x2 = KL.BatchNormalization()(x2) 32 | x2 = KL.Activation('relu')(x2) 33 | x2 = KL.Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same')(x2) 34 | x2 = KL.BatchNormalization()(x2) 35 | x2 = KL.Activation('relu')(x2) 36 | x2 = KL.LocallyConnected2D(64 , kernel_size=(2,2))(x2) 37 | x2 = KL.BatchNormalization()(x2) 38 | x2 = KL.Activation('relu')(x2) 39 | f2 = KL.Flatten()(x2) 40 | 41 | 42 | #拼接 43 | s1 = KL.Dense(128)(f1) 44 | s1 = KL.Activation('relu')(s1) 45 | s1 = KL.BatchNormalization()(s1) 46 | 47 | s2 = KL.Concatenate()([f1,f2]) 48 | s2 = KL.Dense(128)(s2) 49 | s2 = KL.Activation('relu')(s2) 50 | s2 = KL.BatchNormalization()(s2) 51 | s = KL.Concatenate()([s1,s2]) 52 | s = KL.Dense(49, activation='softmax')(s) 53 | 54 | 55 | model = tf.keras.Model(inputs=[input1, input2], outputs=s) 56 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 57 | loss='categorical_crossentropy', metrics=['accuracy']) 58 | # model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 59 | # loss={"first": 'categorical_crossentropy', 60 | # "second": 'categorical_crossentropy'}, 61 | # loss_weights={"first": 1, 62 | # "second": 1}, 63 | # metrics=['accuracy']) 64 | return model 65 | 66 | 67 | 68 | # 决策层融合的测试,(显存资源不足) 69 | def EnergyAndEmgsoft(): 70 | input1 = KL.Input(shape=(60, 80)) 71 | input11 = tf.expand_dims(input=input1, axis=3) 72 | input2 = KL.Input(shape=(400, 12)) 73 | input21 = tf.expand_dims(input=input2, axis=3) 74 | 75 | #早期融合网络,加入1×1卷积 76 | 77 | x1 = KL.Conv2D(filters=64, kernel_size=(4, 4), strides=(1, 1), padding='same')(input11) 78 | x1 = KL.BatchNormalization()(x1) 79 | x1 = KL.Activation('relu')(x1) 80 | x1 = KL.Conv2D(filters=64, kernel_size=(4, 4), strides=(1, 1), padding='same')(x1) 81 | x1 = KL.BatchNormalization()(x1) 82 | x1 = KL.Activation('relu')(x1) 83 | x1 = KL.Dense(128, activation='relu')(x1) 84 | x1 = KL.Flatten()(x1) 85 | x1 = KL.Dropout(0.2)(x1) 86 | output1 = KL.Dense(49, activation='softmax')(x1) 87 | 88 | x2 = KL.Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same')(input21) 89 | x2 = KL.BatchNormalization()(x2) 90 | x2 = KL.Activation('relu')(x2) 91 | x2 = KL.Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same')(x2) 92 | x2 = KL.BatchNormalization()(x2) 93 | x2 = KL.Activation('relu')(x2) 94 | x2 = KL.LocallyConnected2D(64 , kernel_size=(2,2))(x2) 95 | x2 = KL.BatchNormalization()(x2) 96 | x2 = KL.Activation('relu')(x2) 97 | x2 = KL.Flatten()(x2) 98 | x2 = KL.Dropout(0.2)(x2) 99 | output2 = KL.Dense(49, activation='softmax')(x2) 100 | 101 | #拼接 102 | 103 | s = KL.Add()([output1,output2]) 104 | 105 | model = tf.keras.Model(inputs=[input1, input2], outputs=s) 106 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 107 | loss='categorical_crossentropy', metrics=['accuracy']) 108 | # model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 109 | # loss={"first": 'categorical_crossentropy', 110 | # "second": 'categorical_crossentropy'}, 111 | # loss_weights={"first": 1, 112 | # "second": 1}, 113 | # metrics=['accuracy']) 114 | return model 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /other/skconv.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @Date : 2019.4.16 4 | """ 5 | import tensorflow as tf 6 | import tflearn 7 | import tf_slim as slim 8 | from tensorflow.keras import layers 9 | 10 | def SKConv(input, M, r, L=32, stride=1, is_training=True): 11 | input_feature = input.get_shape().as_list()[3] 12 | d = max(int(input_feature / r), L) 13 | net = input 14 | with slim.arg_scope([slim.conv2d, slim.fully_connected], activation_fn=tf.nn.relu): 15 | for i in range(M): 16 | net = slim.conv2d(net, input_feature, [3+i*2, 3+i*2], rate=1+i, stride=stride) 17 | net = slim.batch_norm(net, decay=0.9, center=True, scale=True, epsilon=1e-5, 18 | updates_collections=tf.GraphKeys.UPDATE_OPS, is_training=is_training) 19 | net = tf.nn.relu(net) 20 | if i == 0: 21 | fea_U = net 22 | else: 23 | fea_U = tf.add(fea_U, net) 24 | gap = tflearn.global_avg_pool(fea_U) 25 | fc = slim.fully_connected(gap, d, activation_fn=None) 26 | fcs = fc 27 | for _ in range(M): 28 | fcs = slim.fully_connected(fcs, input_feature, activation_fn=None) 29 | if _ == 0: 30 | att_vec = fcs 31 | else: 32 | att_vec = tf.add(att_vec, fcs) 33 | att_vec = tf.expand_dims(att_vec, axis=1) 34 | att_vec = tf.expand_dims(att_vec, axis=1) 35 | att_vec_softmax = tf.nn.softmax(att_vec) 36 | fea_v = tf.multiply(fea_U, att_vec_softmax) 37 | return fea_v 38 | 39 | 40 | 41 | def SKConv2(M=2, r=16, L=32, G=32, name='skconv'): 42 | 43 | def wrapper(inputs): 44 | inputs_shape = tf.shape(inputs) 45 | b, h, w = inputs_shape[0], inputs_shape[1], inputs_shape[2] 46 | filters = inputs.get_shape().as_list()[-1] 47 | d = max(filters//r, L) 48 | 49 | x = inputs 50 | 51 | xs = [] 52 | for m in range(1, M+1): 53 | if G == 1: 54 | _x = layers.Conv2D(filters, 3, dilation_rate=m, padding='same', 55 | use_bias=False, name=name+'_conv%d'%m)(x) 56 | else: 57 | c = filters // G 58 | _x = layers.DepthwiseConv2D(3, dilation_rate=m, depth_multiplier=c, padding='same', 59 | use_bias=False, name=name+'_conv%d'%m)(x) 60 | 61 | _x = layers.Reshape([h, w, G, c, c], name=name+'_conv%d_reshape1'%m)(_x) 62 | _x = layers.Lambda(lambda x: tf.reduce_sum(x, axis=-1), 63 | output_shape=[b, h, w, G, c], 64 | name=name+'_conv%d_sum'%m)(_x) 65 | _x = layers.Reshape([h, w, filters], 66 | name=name+'_conv%d_reshape2'%m)(_x) 67 | 68 | 69 | _x = layers.BatchNormalization(name=name+'_conv%d_bn'%m)(_x) 70 | _x = layers.Activation('relu', name=name+'_conv%d_relu'%m)(_x) 71 | 72 | xs.append(_x) 73 | 74 | U = layers.Add(name=name+'_add')(xs) 75 | s = layers.Lambda(lambda x: tf.reduce_mean(x, axis=[1,2], keepdims=True), 76 | output_shape=[b, 1, 1, filters], 77 | name=name+'_gap')(U) 78 | 79 | z = layers.Conv2D(d, 1, name=name+'_fc_z')(s) 80 | z = layers.BatchNormalization(name=name+'_fc_z_bn')(z) 81 | z = layers.Activation('relu', name=name+'_fc_z_relu')(z) 82 | 83 | x = layers.Conv2D(filters*M, 1, name=name+'_fc_x')(z) 84 | x = layers.Reshape([1, 1, filters, M],name=name+'_reshape')(x) 85 | scale = layers.Softmax(name=name+'_softmax')(x) 86 | 87 | x = layers.Lambda(lambda x: tf.stack(x, axis=-1), 88 | output_shape=[b, h, w, filters, M], 89 | name=name+'_stack')(xs) # b, h, w, c, M 90 | x = Axpby(name=name+'_axpby')([scale, x]) 91 | 92 | return x 93 | return wrapper 94 | 95 | class Axpby(layers.Layer): 96 | """ 97 | Do this: 98 | F = a * X + b * Y + ... 99 | Shape info: 100 | a: B x 1 x 1 x C 101 | X: B x H x W x C 102 | b: B x 1 x 1 x C 103 | Y: B x H x W x C 104 | ... 105 | F: B x H x W x C 106 | """ 107 | def __init__(self, **kwargs): 108 | super(Axpby, self).__init__(**kwargs) 109 | 110 | def build(self, input_shape): 111 | super(Axpby, self).build(input_shape) # Be sure to call this at the end 112 | 113 | def call(self, inputs): 114 | """ scale: [B, 1, 1, C, M] 115 | x: [B, H, W, C, M] 116 | """ 117 | scale, x = inputs 118 | f = tf.multiply(scale, x, name='product') 119 | f = tf.reduce_sum(f, axis=-1, name='sum') 120 | return f 121 | 122 | def compute_output_shape(self, input_shape): 123 | return input_shape[0:4] -------------------------------------------------------------------------------- /Models/PopularModel/Vnet.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras.layers import * 3 | 4 | def downstage_resBlock(x, stage_id, keep_prob, stage_num=5): 5 | """ 6 | Vnet左侧的压缩路径的一个stage层 7 | :param x: 该stage的输入 8 | :param stage_id: int,表示第几个stage,原论文中从上到下依次是1-5 9 | :param keep_prob: dropout保留元素的概率,如果不需要则设置为1 10 | :param stage_num: stage_num是Vnet设置的stage总数 11 | :return: stage下采样后的输出和stage下采样前的输出,下采样前的输出需要与Vnet右侧的扩展路径连接,所以需要输出保存。 12 | """ 13 | x0 = x # x0是stage的原始输入 14 | # Vnet每个stage的输入会进行特定次数的卷积操作,1~3个stage分别执行1~3次卷积,3以后的stage均执行3次卷积 15 | # 每个stage的通道数(卷积核个数或叫做feature map数量)依次增加两倍,从16,32,64,128到256 16 | for _ in range(3 if stage_id > 3 else stage_id): 17 | x = Conv2D(16 * (2 ** (stage_id - 1)), 5, activation=None, padding='same', kernel_initializer='he_normal')(x) 18 | x = BatchNormalization()(x) 19 | x = ReLU()(x) 20 | print('conv_down_stage_%d:' % stage_id, x.get_shape().as_list()) # 输出收缩路径中每个stage内的卷积 21 | x_add = ReLU()(add([x0, x])) 22 | x_add = Dropout(keep_prob)(x_add) 23 | 24 | if stage_id < stage_num: 25 | x_downsample = Conv2D(16 * (2 ** stage_id), 2, strides=(2, 2), activation=None, padding='same',kernel_initializer='he_normal')(x_add) 26 | x_downsample= BatchNormalization()(x_downsample) 27 | x_downsample = ReLU()(x_downsample) 28 | return x_downsample, x_add # 返回每个stage下采样后的结果,以及在相加之后的结果 29 | else: 30 | return x_add, x_add # 返回相加之后的结果,为了和上面输出保持一致,所以重复输出 31 | 32 | 33 | def upstage_resBlock(forward_x, x, stage_id): 34 | """ 35 | Vnet右侧的扩展路径的一个stage层 36 | :param forward_x: 对应压缩路径stage层下采样前的特征,与当前stage的输入进行叠加(不是相加),补充压缩损失的特征信息 37 | :param x: 当前stage的输入 38 | :param stage_id: 当前stage的序号,右侧stage的序号和左侧是一样的,从下至上是5到1 39 | :return:当前stage上采样后的输出 40 | """ 41 | input = concatenate([forward_x, x], axis=-1) 42 | for _ in range(3 if stage_id > 3 else stage_id): 43 | input = Conv2D(16 * (2 ** (stage_id - 1)), 5, activation=None, padding='same', kernel_initializer='he_normal')(input) 44 | input = BatchNormalization()(input) 45 | input = ReLU()(input) 46 | print('conv_down_stage_%d:' % stage_id, x.get_shape().as_list()) # 输出收缩路径中每个stage内的卷积 47 | conv_add = ReLU()(add([x, input])) 48 | if stage_id > 1: 49 | # 上采样的卷积也称为反卷积,或者叫转置卷积 50 | conv_upsample=Conv2DTranspose(16 * (2 ** (stage_id - 2)), 2, strides=(2, 2), padding='valid', activation=None, 51 | kernel_initializer='he_normal')(conv_add) 52 | conv_upsample =BatchNormalization()(conv_upsample) 53 | conv_upsample = ReLU()(conv_upsample) 54 | return conv_upsample 55 | else: 56 | return conv_add 57 | 58 | 59 | # 60 | # def Vnet(pretrained_weights=None, input_size=(256, 256, 1), num_class=1, is_training=True, stage_num=5): 61 | # """ 62 | # Vnet网络构建 63 | # :param pretrained_weights:是否加载预训练参数 64 | # :param input_size: 输入图像尺寸(w,h,c),c是通道数 65 | # :param num_class: 数据集的类别总数 66 | # :param is_training: 是否是训练模式 67 | # :param stage_num: Vnet的网络深度,即stage的总数,论文中为5 68 | # :return: Vnet网络模型 69 | # """ 70 | # keep_prob = 0.5 if is_training else 1.0 # dropout概率 71 | # left_featuremaps = [] 72 | # input_data = Input(input_size) 73 | # x = PReLU()(BatchNormalization()( 74 | # Conv2D(16, 5, activation=None, padding='same', kernel_initializer='he_normal')(input_data))) 75 | # 76 | # # 数据经过Vnet左侧压缩路径处理 77 | # for s in range(1, stage_num + 1): 78 | # x, featuremap = downstage_resBlock(x, s, keep_prob, stage_num) 79 | # left_featuremaps.append(featuremap) # 记录左侧每个stage下采样前的特征 80 | # 81 | # # Vnet左侧路径跑完后,需要进行一次上采样(反卷积) 82 | # x_up = PReLU()(BatchNormalization()( 83 | # Conv2DTranspose(16 * (2 ** (s - 2)), 2, strides=(2, 2), padding='valid', activation=None, 84 | # kernel_initializer='he_normal')(x))) 85 | # 86 | # # 数据经过Vnet右侧扩展路径处理 87 | # for d in range(stage_num - 1, 0, -1): 88 | # x_up = upstage_resBlock(left_featuremaps[d - 1], x_up, d) 89 | # if num_class > 1: 90 | # conv_out = Conv2D(num_class, 1, activation='softmax', padding='same', kernel_initializer='he_normal')(x_up) 91 | # else: 92 | # conv_out = Conv2D(num_class, 1, activation='sigmoid', padding='same', kernel_initializer='he_normal')(x_up) 93 | # 94 | # model = K.Model(inputs=input_data, outputs=conv_out) 95 | # print(model.output_shape) 96 | # 97 | # if num_class > 1: 98 | # model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001, momentum=0.99, decay=1e-6), loss='sparse_categorical_crossentropy', 99 | # metrics=['ce']) # metrics看看需不需要修改 100 | # else: 101 | # model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001, momentum=0.99, decay=1e-6), loss='binary_crossentropy', 102 | # metrics=['binary_accuracy']) 103 | # if pretrained_weights: 104 | # model.load_weights(pretrained_weights) 105 | # # plot_model(model, to_file='model.png') # 绘制网络结构 106 | # return model 107 | -------------------------------------------------------------------------------- /Util/feature_set.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | from sklearn.model_selection import train_test_split, StratifiedKFold 4 | from sklearn.preprocessing import StandardScaler 5 | from scipy import signal 6 | import os 7 | import pywt 8 | from tqdm import tqdm 9 | from sklearn.decomposition import PCA 10 | import scipy as sp 11 | 12 | 13 | # DWPT分解 14 | def emg_dwpt(signal, wavelet_name='db1'): 15 | wavelet_level = int(np.log2(len(signal))) 16 | wp = pywt.WaveletPacket(signal, wavelet_name, mode='sym') 17 | coeffs = [] 18 | level_coeff = wp.get_level(wavelet_level) 19 | for i in range(len(level_coeff)): 20 | coeffs.append(level_coeff[i].data) 21 | coeffs = np.array(coeffs) 22 | coeffs = coeffs.flatten() 23 | return coeffs 24 | 25 | 26 | ''' ---频域特征分隔线--- ''' 27 | 28 | 29 | def fft(data): 30 | return np.fft.fft(data) 31 | 32 | 33 | # (样本为20时,输出20) 34 | def psd(data): 35 | return np.abs(np.fft.fft(data)) ** 2 36 | 37 | # Mean frequency 38 | def mean_freq(frequency, power): 39 | num = 0 40 | den = 0 41 | for i in range(int(len(power) / 2)): 42 | num += frequency[i] * power[i] 43 | den += power[i] 44 | 45 | return num / den 46 | 47 | # Median frequency 48 | def median_freq(frequency, power): 49 | power_total = np.sum(power) / 2 50 | temp = 0 51 | tol = 0.01 52 | errel = 1 53 | i = 0 54 | 55 | while abs(errel) > tol: 56 | temp += power[i] 57 | errel = (power_total - temp) / power_total 58 | i += 1 59 | if errel < 0: 60 | errel = 0 61 | i -= 1 62 | 63 | return frequency[i] 64 | 65 | 66 | ''' ---时域特征分隔线--- ''' 67 | 68 | 69 | 70 | 71 | def iemg(data): 72 | return np.sum(np.abs(data)) 73 | 74 | def mav(data): 75 | signal_abs = [abs(s) for s in data] 76 | signal_abs = np.array(signal_abs) 77 | if len(signal_abs) == 0: 78 | return 0 79 | else: 80 | return np.mean(signal_abs) 81 | 82 | def wl(data): 83 | return np.sum(abs(np.diff(data))) 84 | 85 | def var(data): 86 | return np.var(data) 87 | 88 | def rms(data): 89 | return np.sqrt(np.mean(data ** 2)) 90 | 91 | 92 | # (20) 93 | def hist(data, nbins=20): 94 | histsig, bin_edges = np.histogram(data, bins=nbins) 95 | return tuple(histsig) 96 | 97 | 98 | # (1) 99 | def entropy(data): 100 | pk = sp.stats.rv_histogram(np.histogram(data, bins=20)).pdf(data) 101 | return sp.stats.entropy(pk) 102 | 103 | 104 | # (1) 105 | def kurtosis(data): 106 | return sp.stats.kurtosis(data) 107 | 108 | 109 | # np.diff后一个元素减去前一个,np.sign返回由1和-1组成的数组 110 | def zero_cross(data): 111 | return len(np.where(np.diff(np.sign(data)))[0]) 112 | 113 | 114 | def min(data): 115 | return np.min(data) 116 | 117 | 118 | def max(data): 119 | return np.max(data) 120 | 121 | 122 | def mean(data): 123 | return np.mean(data) 124 | 125 | 126 | def median(data): 127 | return np.median(data) 128 | 129 | def emg_ssc(signal, threshold=1e-5): 130 | signal = np.array(signal) 131 | temp = [(signal[i] - signal[i - 1]) * (signal[i] - signal[i + 1]) for i in range(1, signal.shape[0] - 1, 1)] 132 | temp = np.array(temp) 133 | 134 | temp = temp[temp >= threshold] 135 | return temp.shape[0] 136 | 137 | 138 | def emg_hemg(signal, bins): 139 | signal = np.array(signal) 140 | hist, bin_edge = np.histogram(signal, bins) 141 | return hist 142 | 143 | 144 | 145 | 146 | def frequency_features_estimation(signal, fs, frame, step): 147 | """ 148 | Compute frequency features from signal using sliding window method. 149 | :param signal: numpy array signal. 150 | :param fs: sampling frequency of the signal. 151 | :param frame: sliding window size 152 | :param step: sliding window step size 153 | :return: frequency_features_matrix: narray matrix with the frequency features stacked by columns. 154 | """ 155 | 156 | fr = [] 157 | mnp = [] 158 | mnf = [] 159 | mdf = [] 160 | pkf = [] 161 | 162 | for i in range(frame, signal.size, step): 163 | x = signal[i - frame:i] 164 | frequency, power = spectrum(x, fs) 165 | 166 | fr.append(frequency_ratio(frequency, power)) # Frequency ratio 167 | mnp.append(np.sum(power) / len(power)) # Mean power 168 | mnf.append(mean_freq(frequency, power)) # Mean frequency 169 | mdf.append(median_freq(frequency, power)) # Median frequency 170 | pkf.append(frequency[power.argmax()]) # Peak frequency 171 | 172 | frequency_features_matrix = np.column_stack((fr, mnp, mnf, mdf, pkf)) 173 | 174 | return frequency_features_matrix 175 | 176 | 177 | def frequency_ratio(frequency, power): 178 | power_low = power[(frequency >= 30) & (frequency <= 250)] 179 | power_high = power[(frequency > 250) & (frequency <= 500)] 180 | ULC = np.sum(power_low) 181 | UHC = np.sum(power_high) 182 | 183 | return ULC / UHC 184 | 185 | 186 | 187 | def spectrum(signal, fs): 188 | m = len(signal) 189 | n = next_power_of_2(m) 190 | y = np.fft.fft(signal, n) 191 | yh = y[0:int(n / 2 - 1)] 192 | fh = (fs / n) * np.arange(0, n / 2 - 1, 1) 193 | power = np.real(yh * np.conj(yh) / n) 194 | 195 | return fh, power 196 | 197 | def next_power_of_2(x): 198 | return 1 if x == 0 else 2 ** (x - 1).bit_length() -------------------------------------------------------------------------------- /Preprocess/GetEnergy.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import h5py 3 | import pandas as pd 4 | import numpy as np 5 | from mpl_toolkits.axisartist import SubplotZero 6 | from tqdm import tqdm 7 | 8 | 9 | def rect_sum(amplitude, v): 10 | '''绘制矩形''' 11 | xmax = np.max(amplitude) 12 | xmin = np.min(amplitude) 13 | xavg = np.average(amplitude) 14 | ymax = np.max(v) 15 | ymin = np.min(v) 16 | yavg = np.average(v) 17 | 18 | N1 = 20 19 | N2 = 20 20 | 21 | w = (xmax - xmin) / N1 22 | l = (ymax - ymin) / N2 23 | 24 | '''target存储了相图坐标, GSMatrix为灰度矩阵''' 25 | GSMatrix = np.zeros([N1, N2], dtype=np.float32) 26 | targets = list(zip(amplitude, v)) 27 | for target in targets: 28 | X_Matrix = int((target[0]-xmin)/w)-1 29 | Y_Matrix = int((target[1]-ymin)/l)-1 30 | GSMatrix[X_Matrix, Y_Matrix] = GSMatrix[X_Matrix, Y_Matrix] + 1 31 | 32 | '''2D移动均值法''' 33 | GSMatrix_Mov = np.zeros([N1, N2], dtype=np.float32) 34 | for i in range(1,N1-1): 35 | for j in range(1, N2 - 1): 36 | GSMatrix_Mov[i, j] = (GSMatrix[i - 1, j - 1] + GSMatrix[i - 1, j] + GSMatrix[i - 1, j + 1] 37 | + GSMatrix[i, j - 1] + GSMatrix[i, j] + GSMatrix[i, j + 1] 38 | + GSMatrix[i + 1, j - 1] + GSMatrix[i + 1, j] + GSMatrix[i + 1, j + 1]) / 9 39 | 40 | 41 | '''I表示为加入权重的灰度矩阵,w * l为不同相图的单元格面积''' 42 | I = GSMatrix_Mov * (w * l) 43 | # B = I.astype(np.int) 44 | 45 | return I 46 | 47 | 48 | def channel_join(emg_arr, channel=12): 49 | N1 = 20 50 | N2 = 20 51 | splice_matrix = [] 52 | for iemg in (tqdm(emg_arr)): 53 | # 多通道灰度图的拼接占位 54 | join_map = np.zeros([N1 * 3, N2 * 4], dtype=np.float32) 55 | one_matrix = [] 56 | for i in range(channel): 57 | amplitude, v = energy(iemg[:, i]) 58 | one_map = rect_sum(amplitude, np.array(v)) 59 | #生成60*80的拼接矩阵 60 | a = int(i / 4) 61 | b = i % 4 62 | join_map[a * N1:(a + 1) * N1, b * N2:(b + 1) * N2] = one_map 63 | 64 | one_matrix.append(rect_sum(amplitude, np.array(v))) 65 | splice_matrix.append(join_map) 66 | aaaa = np.array(splice_matrix) 67 | return np.array(splice_matrix) 68 | 69 | 70 | def energy(iemg): 71 | v = [] 72 | for i in range(len(iemg)): 73 | if i == 0: 74 | sum = iemg[i] - 0 75 | else: 76 | sum = iemg[i] - iemg[i - 1] 77 | v.append(sum.astype(np.float32)) 78 | return iemg, v 79 | 80 | 81 | 82 | def energy_map(iemg, freq=2000): 83 | y = [] 84 | for i in range(len(iemg)): 85 | if i == 0: 86 | sum = iemg[i] - 0 87 | else: 88 | sum = iemg[i] - iemg[i - 1] 89 | y.append(sum) 90 | y2 = np.array(y) 91 | 92 | fig = plt.figure(1, (10, 6)) 93 | ax = SubplotZero(fig, 1, 1, 1) 94 | fig.add_subplot(ax) 95 | 96 | """新建坐标轴""" 97 | ax.axis["xzero"].set_visible(True) 98 | # ax.axis["xzero"].label.set_text("y=0") 99 | # ax.axis["xzero"].label.set_color('green') 100 | ax.axis['yzero'].set_visible(True) 101 | # ax.axis["yzero"].label.set_text("x=0") 102 | 103 | """坐标箭头""" 104 | ax.axis["xzero"].set_axisline_style("-|>") 105 | ax.axis["yzero"].set_axisline_style("-|>") 106 | 107 | """隐藏坐标轴""" 108 | ax.axis["top", 'right', 'left', 'bottom'].set_visible(False) 109 | 110 | """设置刻度""" 111 | # ax.set_ylim(-3, 3) 112 | # ax.set_yticks([-1, -0.5, 0, 0.5, 1]) 113 | # ax.set_xlim([-5, 8]) 114 | # ax.set_xticks([-5,5,1]) 115 | 116 | # 设置网格样式 117 | ax.grid(True, linestyle='-.') 118 | 119 | rect_sum(iemg[:], y) 120 | ax.scatter(iemg[:], y, s=4) 121 | # plt.plot(iemg[:], y, linestyle='-.') 122 | plt.show() 123 | 124 | 125 | for j in range(1, 2): 126 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/df_Seg/DB2_s' + str(j) + 'Seg17.h5', 'r') 127 | x_train1, x_train3, x_train4, x_train6 = file['x_train1'][:],file['x_train3'][:],file['x_train4'][:],file['x_train6'][:] 128 | y_train1,y_train3,y_train4,y_train6 = file['y_train1'][:],file['y_train3'][:],file['y_train4'][:],file['y_train6'][:] 129 | x_test = file['x_test'][:] 130 | y_test = file['y_test'][:] 131 | file.close() 132 | 133 | # sample = x_train1[:50, :, :] 134 | map1 = channel_join(x_train1, 12) 135 | map3 = channel_join(x_train3, 12) 136 | map4 = channel_join(x_train4, 12) 137 | map6 = channel_join(x_train6, 12) 138 | maptest = channel_join(x_test,12) 139 | 140 | # 存储为h5文件 141 | file = h5py.File('D:/Pengxiangdong/ZX/DB2/data/energy_map/DB2_s' + str(j) + 'map17.h5', 'w') 142 | file.create_dataset('map1', data=map1.astype('float32')) 143 | file.create_dataset('map3', data=map3.astype('float32')) 144 | file.create_dataset('map4', data=map4.astype('float32')) 145 | file.create_dataset('map6', data=map6.astype('float32')) 146 | file.create_dataset('y_train1', data=y_train1.astype('int')) 147 | file.create_dataset('y_train3', data=y_train3.astype('int')) 148 | file.create_dataset('y_train4', data=y_train4.astype('int')) 149 | file.create_dataset('y_train6', data=y_train6.astype('int')) 150 | 151 | file.create_dataset('maptest', data=maptest.astype('float32')) 152 | file.create_dataset('y_test', data=y_test.astype('int')) 153 | file.close() 154 | 155 | print('******************DB2_s' + str(j) + '完成***********************') 156 | 157 | -------------------------------------------------------------------------------- /Models/DBEmgNet/emgFile.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import regularizers 3 | from tensorflow.keras import backend as K 4 | from tensorflow.keras import layers as KL 5 | 6 | from Models.DBlayers.CBAM import cbam_time, cbam_acquisition 7 | 8 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 9 | 10 | 11 | 12 | # 3条支路,每个支路做串行的卷积注意力,在网络层加入标准化,注意顺序,早期网络加入1×1卷积 13 | def Away3reluBNCBAMcat(): 14 | input1 = KL.Input(shape=(400, 8)) 15 | input11 = tf.expand_dims(input=input1, axis=3) 16 | input2 = KL.Input(shape=(400, 2)) 17 | input21 = tf.expand_dims(input=input2, axis=3) 18 | input3 = KL.Input(shape=(400, 2)) 19 | input31 = tf.expand_dims(input=input3, axis=3) 20 | #早期融合网络,加入1×1卷积 21 | c1 = KL.Concatenate(axis=-2)([input11, input21, input31]) 22 | c1 = KL.Conv2D(filters=32, kernel_size=(1, 1), strides=(1, 1),kernel_regularizer=regularizers.l2(0.01), activation='relu', padding='same')(c1) 23 | 24 | 25 | x1 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input11) 26 | x1 = KL.BatchNormalization()(x1) 27 | x1 = cbam_time(x1) 28 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), activation='relu', padding='same')(x1) 29 | x1 = KL.BatchNormalization()(x1) 30 | output1 = cbam_acquisition(x1) 31 | 32 | 33 | x2 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input21) 34 | x2 = KL.BatchNormalization()(x2) 35 | x2 = cbam_time(x2) 36 | x2 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x2) 37 | x2 = KL.BatchNormalization()(x2) 38 | output2 = cbam_acquisition(x2) 39 | 40 | 41 | x3 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input31) 42 | x3 = KL.BatchNormalization()(x3) 43 | x3 = cbam_time(x3) 44 | x3 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x3) 45 | x3 = KL.BatchNormalization()(x3) 46 | output3 = cbam_acquisition(x3) 47 | 48 | 49 | c2 = KL.Concatenate(axis=-2)([output1, output2, output3]) 50 | c = KL.Concatenate(axis=-1)([c1, c2]) 51 | X = KL.GlobalAvgPool2D()(c) 52 | X = KL.Dense(256, activation='relu')(X) 53 | X = KL.Dropout(0.1)(X) 54 | s = KL.Dense(49, activation='softmax')(X) 55 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 56 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 57 | loss='categorical_crossentropy', metrics=['accuracy']) 58 | return model 59 | 60 | 61 | 62 | 63 | def reluBNCBAMcat(): 64 | input1 = KL.Input(shape=(400, 12)) 65 | input11 = tf.expand_dims(input=input1, axis=-1) 66 | 67 | 68 | # 早期融合网络,加入1×1卷积 69 | x1 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input11) 70 | x1 = KL.BatchNormalization()(x1) 71 | x1 = cbam_time(x1) 72 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 12), strides=(1, 1), activation='relu', padding='same')(x1) 73 | x1 = KL.BatchNormalization()(x1) 74 | x1 = cbam_acquisition(x1) 75 | x1 = KL.GlobalAvgPool2D()(x1) 76 | 77 | X = KL.Dense(512, activation='relu')(x1) 78 | X = KL.Dropout(0.1)(X) 79 | s = KL.Dense(49, activation='softmax')(X) 80 | model = tf.keras.Model(inputs=input1, outputs=s) 81 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 82 | loss='categorical_crossentropy', metrics=['accuracy']) 83 | return model 84 | 85 | 86 | def Away3reluBNCBAMsoft(): 87 | input1 = KL.Input(shape=(400, 8)) 88 | input11 = tf.expand_dims(input=input1, axis=3) 89 | input2 = KL.Input(shape=(400, 2)) 90 | input21 = tf.expand_dims(input=input2, axis=3) 91 | input3 = KL.Input(shape=(400, 2)) 92 | input31 = tf.expand_dims(input=input3, axis=3) 93 | #早期融合网络,加入1×1卷积 94 | c1 = KL.Concatenate(axis=-2)([input11, input21, input31]) 95 | c1 = KL.Conv2D(filters=32, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(c1) 96 | 97 | 98 | x1 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input11) 99 | x1 = KL.BatchNormalization()(x1) 100 | x1 = cbam_time(x1) 101 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), activation='relu', padding='same')(x1) 102 | x1 = KL.BatchNormalization()(x1) 103 | output1 = cbam_acquisition(x1) 104 | 105 | 106 | x2 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input21) 107 | x2 = KL.BatchNormalization()(x2) 108 | x2 = cbam_time(x2) 109 | x2 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x2) 110 | x2 = KL.BatchNormalization()(x2) 111 | output2 = cbam_acquisition(x2) 112 | 113 | 114 | x3 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input31) 115 | x3 = KL.BatchNormalization()(x3) 116 | x3 = cbam_time(x3) 117 | x3 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x3) 118 | x3 = KL.BatchNormalization()(x3) 119 | output3 = cbam_acquisition(x3) 120 | 121 | 122 | c2 = KL.Concatenate(axis=-2)([output1, output2, output3]) 123 | c = KL.Concatenate(axis=-1)([c1, c2]) 124 | X = KL.GlobalAvgPool2D()(c) 125 | X = KL.Dense(512, activation='relu')(X) 126 | X = KL.Dropout(0.1)(X) 127 | s = KL.Dense(49, activation='softmax')(X) 128 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 129 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 130 | loss='categorical_crossentropy', metrics=['accuracy']) 131 | return model 132 | 133 | 134 | -------------------------------------------------------------------------------- /Models/PopularModel/XiaoRong.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import backend as K 3 | from tensorflow.keras import layers as KL 4 | 5 | 6 | 7 | ''' 消融实验---多流批标准化''' 8 | def Away3reluBConv(): 9 | input1 = KL.Input(shape=(400, 8)) 10 | input11 = tf.expand_dims(input=input1, axis=3) 11 | input2 = KL.Input(shape=(400, 2)) 12 | input21 = tf.expand_dims(input=input2, axis=3) 13 | input3 = KL.Input(shape=(400, 2)) 14 | input31 = tf.expand_dims(input=input3, axis=3) 15 | 16 | x1 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input11) 17 | x1 = KL.BatchNormalization()(x1) 18 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), activation='relu', padding='same')(x1) 19 | x1 = KL.BatchNormalization()(x1) 20 | output1 =x1 21 | 22 | x2 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input21) 23 | x2 = KL.BatchNormalization()(x2) 24 | x2 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x2) 25 | x2 = KL.BatchNormalization()(x2) 26 | output2 = x2 27 | 28 | x3 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input31) 29 | x3 = KL.BatchNormalization()(x3) 30 | x3 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x3) 31 | x3 = KL.BatchNormalization()(x3) 32 | output3 = x3 33 | 34 | c = KL.Concatenate(axis=-2)([output1, output2, output3]) 35 | X = KL.GlobalAvgPool2D()(c) 36 | X = KL.Dense(512, activation='relu')(X) 37 | X = KL.Dropout(0.1)(X) 38 | s = KL.Dense(49, activation='softmax')(X) 39 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 40 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 41 | loss='categorical_crossentropy', metrics=['accuracy']) 42 | return model 43 | 44 | 45 | def Away3reluBConv2(): 46 | input1 = KL.Input(shape=(400, 8)) 47 | input11 = tf.expand_dims(input=input1, axis=3) 48 | input2 = KL.Input(shape=(400, 2)) 49 | input21 = tf.expand_dims(input=input2, axis=3) 50 | input3 = KL.Input(shape=(400, 2)) 51 | input31 = tf.expand_dims(input=input3, axis=3) 52 | 53 | x1 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input11) 54 | x1 = KL.BatchNormalization()(x1) 55 | x1 = KL.Activation('relu')(x1) 56 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), padding='same')(x1) 57 | x1 = KL.BatchNormalization()(x1) 58 | x1 = KL.Activation('relu')(x1) 59 | output1 = x1 60 | 61 | x2 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input21) 62 | x2 = KL.Activation('relu')(x2) 63 | x2 = KL.BatchNormalization()(x2) 64 | x2 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), padding='same')(x2) 65 | x2 = KL.BatchNormalization()(x2) 66 | x2 = KL.Activation('relu')(x2) 67 | output2 = x2 68 | 69 | x3 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input31) 70 | x3 = KL.BatchNormalization()(x3) 71 | x3 = KL.Activation('relu')(x3) 72 | x3 = KL.Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), padding='same')(x3) 73 | x3 = KL.BatchNormalization()(x3) 74 | x3 = KL.Activation('relu')(x3) 75 | output3 = x3 76 | 77 | c = KL.Concatenate(axis=-2)([output1, output2, output3]) 78 | X = KL.GlobalAvgPool2D()(c) 79 | X = KL.Dense(128, activation='relu')(X) 80 | X = KL.Dropout(0.2)(X) 81 | s = KL.Dense(49, activation='softmax')(X) 82 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 83 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.01), 84 | loss='categorical_crossentropy', metrics=['accuracy']) 85 | return model 86 | 87 | 88 | 89 | 90 | 91 | ''' 消融实验---单流批标准化''' 92 | def SinglereluBN(): 93 | input1 = KL.Input(shape=(400, 8)) 94 | input11 = tf.expand_dims(input=input1, axis=3) 95 | input2 = KL.Input(shape=(400, 2)) 96 | input21 = tf.expand_dims(input=input2, axis=3) 97 | input3 = KL.Input(shape=(400, 2)) 98 | input31 = tf.expand_dims(input=input3, axis=3) 99 | #早期融合网络,加入1×1卷积 100 | c1 = KL.Concatenate(axis=-2)([input11, input21, input31]) 101 | 102 | 103 | x1 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(c1) 104 | x1 = KL.BatchNormalization()(x1) 105 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), activation='relu', padding='same')(x1) 106 | x1 = KL.BatchNormalization()(x1) 107 | output1 =x1 108 | 109 | 110 | X = KL.GlobalAvgPool2D()(output1) 111 | X = KL.Dense(512, activation='relu')(X) 112 | X = KL.Dropout(0.1)(X) 113 | s = KL.Dense(49, activation='softmax')(X) 114 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 115 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 116 | loss='categorical_crossentropy', metrics=['accuracy']) 117 | return model 118 | 119 | 120 | ''' 消融实验---单流''' 121 | def Singlerelu(): 122 | input1 = KL.Input(shape=(400, 8)) 123 | input11 = tf.expand_dims(input=input1, axis=3) 124 | input2 = KL.Input(shape=(400, 2)) 125 | input21 = tf.expand_dims(input=input2, axis=3) 126 | input3 = KL.Input(shape=(400, 2)) 127 | input31 = tf.expand_dims(input=input3, axis=3) 128 | #早期融合网络,加入1×1卷积 129 | c1 = KL.Concatenate(axis=-2)([input11, input21, input31]) 130 | 131 | 132 | x1 = KL.Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(c1) 133 | x1 = KL.Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), activation='relu', padding='same')(x1) 134 | output1 =x1 135 | 136 | 137 | X = KL.GlobalAvgPool2D()(output1) 138 | X = KL.Dense(512, activation='relu')(X) 139 | X = KL.Dropout(0.1)(X) 140 | s = KL.Dense(49, activation='softmax')(X) 141 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 142 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 143 | loss='categorical_crossentropy', metrics=['accuracy']) 144 | return model -------------------------------------------------------------------------------- /Models/DBFeaNet/FeaModel.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from keras import regularizers 3 | from tensorflow.keras import backend as K 4 | from tensorflow.keras import layers as KL 5 | from tensorflow.keras.layers import * 6 | 7 | from Models.DBlayers.CBAM import cbam_acquisition, cbam_time 8 | from Models.PopularModel import Vnet 9 | from Models.PopularModel.Vnet import downstage_resBlock, upstage_resBlock 10 | 11 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 12 | 13 | 14 | 15 | 16 | 17 | def Fea_select(): 18 | 19 | input1 = Input(shape=(72, 1)) 20 | 21 | x1 = Conv1D(filters=32, kernel_size=6, strides=1, padding='same')(input1) 22 | x1 = Activation('relu')(x1) 23 | x1 = BatchNormalization()(x1) 24 | # x1 = Conv1D(filters=128, kernel_size=5, strides=1, padding='same')(x1) 25 | # x1 = BatchNormalization()(x1) 26 | # x1 = Activation('relu')(x1) 27 | x1 = LocallyConnected1D(32,1)(x1) 28 | x1 = Activation('relu')(x1) 29 | x1 = BatchNormalization()(x1) 30 | x1 = Dropout(0.5)(x1) 31 | x1 = Dense(128)(x1) 32 | x1 = Activation('relu')(x1) 33 | x1 = BatchNormalization()(x1) 34 | x1 = Dropout(0.5)(x1) 35 | x1 = GlobalAvgPool1D()(x1) 36 | 37 | s = Dense(49, activation='softmax',activity_regularizer=regularizers.l1(0.01))(x1) 38 | model = tf.keras.Model(inputs=input1, outputs=s) 39 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 40 | loss='categorical_crossentropy', metrics=['accuracy']) 41 | return model 42 | 43 | 44 | 45 | 46 | def Fea_select2(): 47 | 48 | input1 = Input(shape=(72, 1)) 49 | 50 | x1 = Conv1D(filters=32, kernel_size=6, strides=1, padding='same')(input1) 51 | x1 = BatchNormalization()(x1) 52 | x1 = Activation('relu')(x1) 53 | # x1 = Conv1D(filters=128, kernel_size=5, strides=1, padding='same')(x1) 54 | # x1 = BatchNormalization()(x1) 55 | # x1 = Activation('relu')(x1) 56 | x1 = LocallyConnected1D(32,1)(x1) 57 | x1 = BatchNormalization()(x1) 58 | x1 = Activation('relu')(x1) 59 | x1 = Dropout(0.5)(x1) 60 | x1 = Dense(128, activation='relu')(x1) 61 | x1 = GlobalAvgPool1D()(x1) 62 | 63 | s = Dense(49, activation='softmax',activity_regularizer=regularizers.l1(0.01))(x1) 64 | model = tf.keras.Model(inputs=input1, outputs=s) 65 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 66 | loss='categorical_crossentropy', metrics=['accuracy']) 67 | return model 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | def Stage1(): 78 | input00 = Input(shape=(20, 12)) 79 | input0 = tf.expand_dims(input=input00, axis=3) 80 | input1 = Input(shape=(16, 16, 12)) 81 | input2 = Input(shape=(16, 16, 12)) 82 | 83 | x0 = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding='same')(input0) 84 | x0 = Conv2D(filters=64, kernel_size=(2, 2), strides=(1, 1), activation='relu', padding='same')(x0) 85 | x0 = LocallyConnected2D(64, (1, 1))(x0) 86 | x0 = LocallyConnected2D(64, (1, 1))(x0) 87 | x0 = Flatten()(x0) 88 | 89 | x1 = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding='same')(input1) 90 | x1 = Conv2D(filters=64, kernel_size=(2, 2), strides=(1, 1), activation='relu', padding='same')(x1) 91 | x1 = LocallyConnected2D(64, (1,1))(x1) 92 | x1 = LocallyConnected2D(64, (1,1))(x1) 93 | x1 = Flatten()(x1) 94 | 95 | x2 = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding='same')(input1) 96 | x2 = Conv2D(filters=64, kernel_size=(2, 2), strides=(1, 1), activation='relu', padding='same')(x2) 97 | x2 = LocallyConnected2D(64, (1, 1))(x2) 98 | x2 = LocallyConnected2D(64, (1, 1))(x2) 99 | x2 = Flatten()(x2) 100 | 101 | c = Add()([x1, x2]) 102 | c = Concatenate()([c, x0]) 103 | X = Dense(512, activation='relu')(c) 104 | X = Dense(256, activation='relu')(X) 105 | s = Dense(49, activation='softmax')(X) 106 | model = tf.keras.Model(inputs=[input00, input1, input2], outputs=s) 107 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 108 | loss='categorical_crossentropy', metrics=['accuracy']) 109 | return model 110 | 111 | 112 | def Stage2(): 113 | input1 = Input(shape=(16, 16, 12)) 114 | input2 = Input(shape=(16, 16, 12)) 115 | 116 | x1 = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding='same')(input1) 117 | x1 = Conv2D(filters=64, kernel_size=(2, 2), strides=(1, 1), activation='relu', padding='same')(x1) 118 | x1 = LocallyConnected2D(64, (1,1))(x1) 119 | x1 = LocallyConnected2D(64, (1,1))(x1) 120 | x1 = Dropout(0.1)(x1) 121 | x1 = Dense(256, activation='relu')(x1) 122 | 123 | x2 = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding='same')(input1) 124 | x2 = Conv2D(filters=64, kernel_size=(2, 2), strides=(1, 1), activation='relu', padding='same')(x2) 125 | x2 = LocallyConnected2D(64, (1, 1))(x2) 126 | x2 = LocallyConnected2D(64, (1, 1))(x2) 127 | x2 = Dropout(0.1)(x2) 128 | x2 = Dense(256, activation='relu')(x2) 129 | 130 | c = Add()([x1, x2]) 131 | X = Dense(256, activation='relu')(c) 132 | X = GlobalAvgPool2D()(X) 133 | s = Dense(49, activation='softmax')(X) 134 | model = tf.keras.Model(inputs=[input1, input2], outputs=s) 135 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 136 | loss='categorical_crossentropy', metrics=['accuracy']) 137 | return model 138 | 139 | 140 | def model3(): 141 | input1 = Input(shape=(36)) 142 | input2 = tf.expand_dims(input=input1, axis=-1) 143 | 144 | x1 = Conv1D(filters=64, kernel_size=2, strides=1, activation='relu', padding='same')(input2) 145 | x1 = BatchNormalization()(x1) 146 | x1 = MaxPooling1D(pool_size=2, strides=1, padding='same')(x1) 147 | x1 = Conv1D(filters=128, kernel_size=4, strides=1, activation='relu', padding='same')(x1) 148 | x1 = BatchNormalization()(x1) 149 | 150 | x1 = MaxPooling1D(pool_size=2, strides=1, padding='same')(x1) 151 | 152 | X = Flatten()(x1) 153 | 154 | # s1 = Dense(17, activation='softmax')(X) 155 | X = Dense(128, activation='relu')(X) 156 | X = Dropout(0.1)(X) 157 | s2 = Dense(49, activation='softmax')(X) 158 | # s = Add()([s1,s2]) 159 | 160 | model = tf.keras.Model(inputs=input1, outputs=s2) 161 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 162 | loss='categorical_crossentropy', metrics=['accuracy']) 163 | return model 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /Models/DBlayers/Densenet.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras.models import Model, save_model, load_model 3 | import tensorflow.keras.layers as KL 4 | 5 | 6 | # model 7 | def DenseLayer(x, nb_filter, bn_size=4, alpha=0.0,drop_rate=0.2): 8 | # Bottleneck layers 9 | # 1x1 Conv的作用是降低特征数量 10 | x = KL.BatchNormalization(axis=3)(x) 11 | x = KL.LeakyReLU(alpha=alpha)(x) 12 | x = KL.Conv2D(bn_size * nb_filter, (1, 1), strides=(1, 1), padding='same')(x) 13 | 14 | # Composite function 15 | x = KL.BatchNormalization(axis=3)(x) 16 | x = KL.LeakyReLU(alpha=alpha)(x) 17 | x = KL.Conv2D(nb_filter, (3, 3), strides=(1, 1), activation='relu', padding='same')(x) 18 | 19 | if drop_rate: x = KL.Dropout(drop_rate)(x) 20 | 21 | return x 22 | 23 | 24 | def DenseBlock(x, nb_layers, growth_rate, drop_rate=0.2): 25 | for nb in range(nb_layers): 26 | conv = DenseLayer(x, nb_filter=growth_rate, drop_rate=drop_rate) 27 | x = KL.concatenate([x, conv], axis=3) 28 | 29 | return x 30 | 31 | 32 | def TransitionLayer(x, compression=0.5, alpha=0.0, is_max=0): 33 | nb_filter = int(x.shape.as_list()[-1] * compression) 34 | x = KL.BatchNormalization(axis=3)(x) 35 | x = KL.LeakyReLU(alpha=alpha)(x) 36 | x = KL.Conv2D(nb_filter, (1, 1), strides=(1, 1), padding='same')(x) 37 | if is_max != 0: 38 | x = KL.MaxPooling2D(pool_size=(2, 1), strides=(2, 1))(x) 39 | else: 40 | x = KL.AveragePooling2D(pool_size=(5, 1), strides=(2, 1))(x) 41 | return x 42 | 43 | 44 | def newDenseNet(): 45 | input1 = KL.Input(shape=(400, 12)) 46 | input11 = tf.expand_dims(input=input1, axis=3) 47 | growth_rate = 12 48 | 49 | x = KL.Conv2D(filters=64, kernel_size=(20, 4), strides=(1, 1), activation='relu', padding='same')(input11) 50 | x = KL.BatchNormalization()(x) 51 | x = DenseBlock(x, 6, growth_rate, drop_rate=0.5) 52 | x = TransitionLayer(x) 53 | x = DenseBlock(x, 6, growth_rate, drop_rate=0.5) 54 | x = TransitionLayer(x) 55 | x = DenseBlock(x, 6, growth_rate, drop_rate=0.5) 56 | x = KL.BatchNormalization(axis=3)(x) 57 | output1 = KL.GlobalAveragePooling2D()(x) 58 | 59 | s = KL.Dense(49, activation='softmax')(output1) 60 | model = tf.keras.Model(inputs=input1, outputs=s) 61 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 62 | loss='categorical_crossentropy', metrics=['accuracy']) 63 | return model 64 | 65 | 66 | ''' 67 | 其他版本的实现方式,网络层次更深 68 | ''' 69 | # def conv_block(x, nb_filter, dropout_rate=None, name=None): 70 | # inter_channel = nb_filter * 4 71 | # 72 | # # 1x1 convolution 73 | # x = KL.BatchNormalization(epsilon=1.1e-5, axis=3, name=name + '_bn1')(x) 74 | # x = KL.Activation('relu', name=name + '_relu1')(x) 75 | # x = KL.Conv2D(inter_channel, 1, 1, name=name + '_conv1', use_bias=False)(x) 76 | # 77 | # if dropout_rate: 78 | # x = KL.Dropout(dropout_rate)(x) 79 | # 80 | # # 3x3 convolution 81 | # x = KL.BatchNormalization(epsilon=1.1e-5, axis=3, name=name + '_bn2')(x) 82 | # x = KL.Activation('relu', name=name + '_relu2')(x) 83 | # x = KL.ZeroPadding2D((1, 1), name=name + '_zeropadding2')(x) 84 | # x = KL.Conv2D(nb_filter, 3, 1, name=name + '_conv2', use_bias=False)(x) 85 | # 86 | # if dropout_rate: 87 | # x = KL.Dropout(dropout_rate)(x) 88 | # 89 | # return x 90 | # 91 | # 92 | # def dense_block(x, stage, nb_layers, nb_filter, growth_rate, dropout_rate=None, 93 | # grow_nb_filters=True, name=None): 94 | # concat_feat = x # store the last layer output 95 | # 96 | # for i in range(nb_layers): 97 | # 98 | # branch = i + 1 99 | # x = conv_block(concat_feat, growth_rate, dropout_rate, 100 | # name=name + str(stage) + '_block' + str(branch)) # 在参考的基础,修改的地方这里应该是相同的growth_rate=32 101 | # concat_feat = KL.Concatenate(axis=3, name=name + str(stage) + '_block' + str(branch))([concat_feat, x]) 102 | # 103 | # if grow_nb_filters: 104 | # nb_filter += growth_rate 105 | # 106 | # return concat_feat, nb_filter 107 | # 108 | # 109 | # def transition_block(x, stage, nb_filter, compression=1.0, dropout_rate=None, name=None): 110 | # 111 | # x = KL.BatchNormalization(epsilon=1.1e-5, axis=3, name=name + str(stage) + '_bn')(x) 112 | # x = KL.Activation('relu', name=name + str(stage) + '_relu')(x) 113 | # 114 | # x = KL.Conv2D(int(nb_filter * compression), 1, 1, name=name + str(stage) + '_conv', use_bias=False)(x) 115 | # 116 | # if dropout_rate: 117 | # x = KL.Dropout(dropout_rate)(x) 118 | # 119 | # x = KL.AveragePooling2D((2, 2), strides=(2, 2), name=name + str(stage) + '_pooling2d')(x) 120 | # 121 | # return x 122 | # 123 | # 124 | # def DenseNet(nb_dense_block=4, growth_rate=32, nb_filter=64, reduction=0.0, dropout_rate=0.0, weight_decay=1e-4, 125 | # classes=1000, weights_path=None): 126 | # compression = 1.0 - reduction 127 | # nb_filter = 64 128 | # nb_layers = [6, 12, 24, 16] # For DenseNet-121 129 | # 130 | # img_input = tf.keras.Input(shape=(224, 224, 3)) 131 | # 132 | # # initial convolution 133 | # x = KL.ZeroPadding2D((3, 3), name='conv1_zeropadding')(img_input) 134 | # x = KL.Conv2D(nb_filter, 7, 2, name='conv1', use_bias=False)(x) 135 | # x = KL.BatchNormalization(epsilon=1.1e-5, axis=3, name='conv1_bn')(x) 136 | # x = KL.Activation('relu', name='relu1')(x) 137 | # x = KL.ZeroPadding2D((1, 1), name='pool1_zeropadding')(x) 138 | # x = KL.MaxPooling2D((3, 3), strides=(2, 2), name='pool1')(x) 139 | # 140 | # # Dense block and Transition layer 141 | # for block_id in range(nb_dense_block - 1): 142 | # stage = block_id + 2 # start from 2 143 | # x, nb_filter = dense_block(x, stage, nb_layers[block_id], nb_filter, growth_rate, 144 | # dropout_rate=dropout_rate, name='Dense') 145 | # 146 | # x = transition_block(x, stage, nb_filter, compression=compression, dropout_rate=dropout_rate, name='Trans') 147 | # nb_filter *= compression 148 | # 149 | # final_stage = stage + 1 150 | # x, nb_filter = dense_block(x, final_stage, nb_layers[-1], nb_filter, growth_rate, 151 | # dropout_rate=dropout_rate, name='Dense') 152 | # 153 | # # top layer 154 | # x = KL.BatchNormalization(name='final_conv_bn')(x) 155 | # x = KL.Activation('relu', name='final_act')(x) 156 | # x = KL.GlobalAveragePooling2D(name='final_pooling')(x) 157 | # x = KL.Dense(classes, activation='softmax', name='fc')(x) 158 | # 159 | # model = Model(img_input, x, name='DenseNet121') 160 | # 161 | # return model 162 | -------------------------------------------------------------------------------- /other/ZscoreSegVal.py: -------------------------------------------------------------------------------- 1 | import math 2 | import os 3 | from copy import deepcopy 4 | import h5py 5 | import matplotlib.pyplot as plt 6 | import numpy as np 7 | from matplotlib import colors 8 | 9 | import EMGImg 10 | 11 | os.environ["CUDA_VISIBLE_DEVICES"] = "1" 12 | 13 | # 按动作次数将手势分割(数据,手势类别,通道数) 14 | def segment(data, dataclass, channel): 15 | data = np.array(data) 16 | Datalist = [] 17 | for j in range(1, dataclass + 1): 18 | num = 0 19 | while (num < 6): 20 | for i in range(data.shape[0]): 21 | if data[i, channel] == j: # alldata最后一维存储标签 22 | start = i 23 | break 24 | for k in range(start, data.shape[0]): 25 | if data[k, channel] == 0: 26 | end = k 27 | break 28 | if k == len(data) - 1: 29 | end = data.shape[0] 30 | break 31 | 32 | print(start, end) 33 | num = num + 1 34 | emg = (deepcopy(data[start:end, 0:channel])) 35 | label = (deepcopy(data[start:end, channel])) 36 | myemg = EMGImg.EMG(emg, label) 37 | Datalist.append(myemg) # 用append将每次动作分割为单独的元素 38 | for m in range(start, end): 39 | data[m, channel] = 100 40 | return Datalist # 返回数据为list类型,保存不同长度的数据 41 | 42 | 43 | # # 构造成图像数据,数据为list,元素为二维array 44 | def creatimg(segList): 45 | testData = [] 46 | testLabel = [] 47 | trainData = [] 48 | trainLabel = [] 49 | valiData = [] 50 | valiLabel = [] 51 | imageLength = 400 52 | stridewindow = 100 53 | 54 | for i in range(len(segList)): 55 | # 在重复进行的手势中,指定第几次手势为测试集 56 | k = i % 6 57 | # 第二次做测试集 58 | if k == 1: 59 | # iemg为单独一次的动作, imagelength采样窗口,将多通道emg数据连续分割 60 | # emg数据放大后方便训练识别 61 | iemg = segList[i].data 62 | BNdata = [] 63 | for m in range(12): 64 | # 均值 65 | average = float(sum(iemg[:, m])) / len(iemg[:, m]) 66 | # 方差 67 | total = 0 68 | for value in iemg[:, m]: 69 | total += (value - average) ** 2 70 | stddev = math.sqrt(total / len(iemg[:, m])) 71 | # z-score标准化方法 72 | BNdata.append([(x - average) / stddev for x in iemg[:, m]]) 73 | BNdata = (np.array(BNdata)).T 74 | length = math.floor((BNdata.shape[0] - imageLength) / stridewindow) + 1 75 | for j in range(length): 76 | subImage = BNdata[stridewindow * j:stridewindow * j + imageLength, :] # 连续分割方式 77 | testData.append(subImage) 78 | index = int(segList[i].label[0]) - 1 79 | testLabel.append(index) 80 | # 第五次做验证集 81 | if k == 4: 82 | # iemg为单独一次的动作, imagelength采样窗口,将多通道emg数据连续分割 83 | # emg数据放大后方便训练识别 84 | iemg = segList[i].data 85 | BNdata = [] 86 | for m in range(12): 87 | # 均值 88 | average = float(sum(iemg[:, m])) / len(iemg[:, m]) 89 | # 方差 90 | total = 0 91 | for value in iemg[:, m]: 92 | total += (value - average) ** 2 93 | stddev = math.sqrt(total / len(iemg[:, m])) 94 | # z-score标准化方法 95 | BNdata.append([(x - average) / stddev for x in iemg[:, m]]) 96 | BNdata = (np.array(BNdata)).T 97 | length = math.floor((BNdata.shape[0] - imageLength) / stridewindow) + 1 98 | for j in range(length): 99 | subImage = BNdata[stridewindow * j:stridewindow * j + imageLength, :] # 连续分割方式 100 | valiData.append(subImage) 101 | index = int(segList[i].label[0]) - 1 102 | valiLabel.append(index) 103 | # 其他做训练集 104 | else: 105 | # iemg为单独一次的动作 106 | iemg = segList[i].data 107 | BNdata = [] 108 | for m in range(12): 109 | # 均值 110 | average = float(sum(iemg[:, m])) / len(iemg[:, m]) 111 | # 方差 112 | total = 0 113 | for value in iemg[:, m]: 114 | total += (value - average) ** 2 115 | stddev = math.sqrt(total / len(iemg[:, m])) 116 | # z-score标准化方法 117 | BNdata.append([(x - average) / stddev for x in iemg[:, m]]) 118 | # 拼接后转置为适应的数据形式 119 | BNdata = (np.array(BNdata)).T 120 | length = math.floor((BNdata.shape[0] - imageLength) / stridewindow) + 1 121 | for j in range(length): 122 | subImage = BNdata[stridewindow * j:stridewindow * j + imageLength, :] # 连续分割方式 123 | trainData.append(subImage) 124 | index = int(segList[i].label[0]) - 1 125 | trainLabel.append(index) 126 | trainData = np.array(trainData) 127 | testData = np.array(testData) 128 | trainLabel = np.array(trainLabel) 129 | testLabel = np.array(testLabel) 130 | valiData = np.array(valiData) 131 | valiLabel = np.array(valiLabel) 132 | 133 | return trainData, trainLabel, testData, testLabel, valiData, valiLabel 134 | 135 | 136 | if __name__ == '__main__': 137 | for j in range(15, 41): 138 | h5 = h5py.File('D:/Pengxiangdong/ZX/data/Originaldata/refilter/DB2_s' + str(j) + 'filter.h5', 'r') 139 | alldata = h5['alldata'] 140 | segList = segment(alldata, 49, 12) 141 | trainData, trainLabel, testData, testLabel, valiData, valiLabel = creatimg(segList) 142 | 143 | file = h5py.File('D:/Pengxiangdong/ZX/data/reSegmentdata/reseg400100mValZsc/DB2_s' + str(j) + 'ValZsc.h5', 'w') 144 | file.create_dataset('trainData', data=trainData) 145 | file.create_dataset('trainLabel', data=trainLabel) 146 | file.create_dataset('testData', data=testData) 147 | file.create_dataset('testLabel', data=testLabel) 148 | file.create_dataset('valiData', data=valiData) 149 | file.create_dataset('valiLabel', data=valiLabel) 150 | file.close() 151 | print('******************DB2_s' + str(j) + '分割完成***********************') 152 | 153 | # emg = segList[1].data 154 | # iSampleRate=2000 155 | # for i in range(12): 156 | # plt.subplot(12, 1, i + 1) 157 | # iSampleCount = len(emg) 158 | # t=np.linspace(0, iSampleCount / iSampleRate, iSampleCount) 159 | # plt.plot(t,emg[:, i]) 160 | # # plt.ylim(-0.00025, 0.00025) 161 | # plt.xlabel("Time(s)") 162 | # # plt.xticks([]) # 去掉横坐标值 163 | # plt.yticks([]) # 去掉纵坐标值 164 | # 165 | # plt.show() 166 | -------------------------------------------------------------------------------- /Models/DBFeaEmgNet/FeaEmgFile.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from keras import regularizers 3 | from tensorflow.keras import layers as KL 4 | from tensorflow.keras.layers import * 5 | 6 | from Models.DBlayers.CBAM import cbam_acquisition, cbam_time 7 | from Models.DBlayers.SENet import se_block 8 | from Models.DBlayers.daNet import danet_resnet101 9 | from Models.PopularModel.Vnet import downstage_resBlock, upstage_resBlock 10 | 11 | 12 | def FeaAndEmg_model1(): 13 | input1 = Input(shape=(400,12)) 14 | input11 = tf.expand_dims(input=input1, axis=3) 15 | input2 = Input(shape=(108, 1)) 16 | 17 | # 早期融合网络,加入1×1卷积 18 | x1 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input11) 19 | x1 = Activation('relu')(x1) 20 | x1 = BatchNormalization()(x1) 21 | x1 = cbam_time(x1) 22 | x1 = Conv2D(filters=128, kernel_size=(1, 12), strides=(1, 2), padding='same')(x1) 23 | x1 = Activation('relu')(x1) 24 | x1 = BatchNormalization()(x1) 25 | x1 = cbam_acquisition(x1) 26 | x1 = Dropout(0.5)(x1) 27 | x1 = Dense(128)(x1) 28 | x1 = GlobalAvgPool2D()(x1) 29 | 30 | x2 = Conv1D(filters=32, kernel_size=6, strides=1, padding='same')(input2) 31 | x2 = BatchNormalization()(x2) 32 | x2 = Activation('relu')(x2) 33 | x2 = LocallyConnected1D(32, 1)(x2) 34 | x2 = BatchNormalization()(x2) 35 | x2 = Activation('relu')(x2) 36 | x2 = Dropout(0.5)(x2) 37 | x2 = Dense(256, activity_regularizer=regularizers.l1(0.01))(x2) 38 | x2 = GlobalAvgPool1D()(x2) 39 | 40 | 41 | X = Concatenate(axis=-1)([x1,x2]) 42 | X = Dense(256, activation='relu')(X) 43 | X = Dropout(0.5)(X) 44 | s = Dense(49, activation='softmax')(X) 45 | model = tf.keras.Model(inputs=[input1,input2], outputs=s) 46 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 47 | loss='categorical_crossentropy', metrics=['accuracy']) 48 | return model 49 | 50 | 51 | def FeaAndEmg_modelsoft(): 52 | input1 = Input(shape=(400,12)) 53 | input11 = tf.expand_dims(input=input1, axis=3) 54 | input2 = Input(shape=(108, 1)) 55 | 56 | # 早期融合网络,加入1×1卷积 57 | x1 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input11) 58 | x1 = Activation('relu')(x1) 59 | x1 = BatchNormalization()(x1) 60 | # x1 = cbam_time(x1) 61 | x1 = Conv2D(filters=128, kernel_size=(1, 12), strides=(1, 1), padding='same')(x1) 62 | x1 = Activation('relu')(x1) 63 | x1 = BatchNormalization()(x1) 64 | # x1 = cbam_acquisition(x1) 65 | x1 = GlobalAvgPool2D()(x1) 66 | x1 = KL.Dense(128, activation='relu')(x1) 67 | x1 = KL.Dropout(0.5)(x1) 68 | s1 = KL.Dense(49, activation='softmax', activity_regularizer=regularizers.l1(0.01))(x1) 69 | 70 | x2 = Conv1D(filters=32, kernel_size=6, strides=1, padding='same')(input2) 71 | x2 = BatchNormalization()(x2) 72 | x2 = Activation('relu')(x2) 73 | x2 = LocallyConnected1D(32, 1)(x2) 74 | x2 = BatchNormalization()(x2) 75 | x2 = Activation('relu')(x2) 76 | x2 = Dropout(0.5)(x2) 77 | x2 = GlobalAvgPool1D()(x2) 78 | s2 = Dense(49, activation='softmax', activity_regularizer=regularizers.l1(0.01))(x2) 79 | 80 | s1 = s1 81 | s2 = s2 82 | s = Add()([s1, s2]) 83 | 84 | model = tf.keras.Model(inputs=[input1,input2], outputs=s1) 85 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 86 | loss='categorical_crossentropy', metrics=['accuracy']) 87 | return model 88 | 89 | 90 | def FeaAndEmg_model2(): 91 | input1 = Input(shape=(400,12)) 92 | input11 = tf.expand_dims(input=input1, axis=3) 93 | input2 = Input(shape=(180, 1)) 94 | 95 | # 早期融合网络,加入1×1卷积 96 | stage_num = 3 97 | left_featuremaps = [] 98 | input_data = input11 99 | x = Conv2D(16, (5, 1), activation=None, padding='same', kernel_initializer='he_normal')(input_data) 100 | x = BatchNormalization()(x) 101 | x = Activation('relu')(x) 102 | 103 | # 数据经过Vnet左侧压缩路径处理 104 | for s in range(1, stage_num + 1): 105 | x, featuremap = downstage_resBlock(x, s, 0.5, stage_num) 106 | left_featuremaps.append(featuremap) # 记录左侧每个stage下采样前的特征 107 | 108 | # Vnet左侧路径跑完后,需要进行一次上采样(反卷积) 109 | x_up= Conv2DTranspose(16 * (2 ** (s - 2)), 2, strides=(2, 2), padding='valid', activation=None, 110 | kernel_initializer='he_normal')(x) 111 | x_up = BatchNormalization()(x_up) 112 | x_up = Activation('relu')(x_up) 113 | # 数据经过Vnet右侧扩展路径处理 114 | for d in range(stage_num - 1, 0, -1): 115 | x_up = upstage_resBlock(left_featuremaps[d - 1], x_up, d) 116 | x1 = Dense(128, activation='relu')(x_up) 117 | x1 = GlobalAvgPool2D()(x1) 118 | 119 | 120 | # x2 = Conv1D(filters=64, kernel_size=3, strides=1, activation='relu', padding='same')(input2) 121 | # x2 = MaxPool1D(pool_size=2, strides=1, padding='same')(x2) 122 | # x2 = Conv1D(filters=128, kernel_size=5, strides=1, activation='relu', padding='same')(x2) 123 | # x2 = MaxPool1D(pool_size=2, strides=1, padding='same')(x2) 124 | 125 | x2 = Conv1D(filters=64, kernel_size=3, strides=1, padding='same')(input2) 126 | x2 = BatchNormalization()(x2) 127 | x2 = Activation('relu')(x2) 128 | x2 = LocallyConnected1D(32, 1)(x2) 129 | x2 = BatchNormalization()(x2) 130 | x2 = Activation('relu')(x2) 131 | x2 = Dropout(0.5)(x2) 132 | 133 | x2 = GlobalAvgPool1D()(x2) 134 | 135 | 136 | X = Concatenate(axis=-1)([x1,x2]) 137 | X = Dense(256, activation='relu')(X) 138 | X = Dropout(0.1)(X) 139 | s = Dense(49, activation='softmax')(X) 140 | model = tf.keras.Model(inputs=[input1,input2], outputs=s) 141 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 142 | loss='categorical_crossentropy', metrics=['accuracy']) 143 | return model 144 | 145 | 146 | 147 | 148 | 149 | def FeaAndEmg_se(): 150 | input1 = KL.Input(shape=(400,12)) 151 | input11 = tf.expand_dims(input=input1, axis=3) 152 | input11 = KL.Reshape(target_shape=(20, 20, 12))(input11) 153 | input2 = KL.Input(shape=(36, 1)) 154 | 155 | # 早期融合网络,加入1×1卷积 156 | 157 | x1 = KL.Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same')(input11) 158 | x1 = KL.BatchNormalization()(x1) 159 | x1 = KL.Activation('relu')(x1) 160 | # x1 = se_block(x1) 161 | x1 = KL.Conv2D(filters=128, kernel_size=(5, 5), strides=(1, 1), padding='same')(x1) 162 | x1 = KL.BatchNormalization()(x1) 163 | x1 = KL.Activation('relu')(x1) 164 | # x1 = se_block(x1) 165 | x1 = KL.GlobalAvgPool2D()(x1) 166 | 167 | 168 | x2 = KL.Conv1D(filters=64, kernel_size=3, strides=1, activation='relu', padding='same')(input2) 169 | x2 = KL.MaxPool1D(pool_size=2, strides=1, padding='same')(x2) 170 | x2 = KL.Conv1D(filters=128, kernel_size=5, strides=1, activation='relu', padding='same')(x2) 171 | x2 = KL.MaxPool1D(pool_size=2, strides=1, padding='same')(x2) 172 | x2 = KL.GlobalAvgPool1D()(x2) 173 | s = KL.Add()([x1, x2]) 174 | 175 | X = KL.Dense(256, activation='relu')(s) 176 | X = KL.Dropout(0.2)(X) 177 | s = KL.Dense(49, activation='softmax')(X) 178 | model = tf.keras.Model(inputs=[input1, input2], outputs=s) 179 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.01), 180 | loss='categorical_crossentropy', metrics=['accuracy']) 181 | return model -------------------------------------------------------------------------------- /Models/DBlayers/daNet.py: -------------------------------------------------------------------------------- 1 | from keras.models import Model 2 | from keras.layers import Input, Activation, Conv2D, Dropout 3 | from keras.layers import MaxPooling2D, BatchNormalization 4 | from keras.layers import UpSampling2D 5 | from keras.layers import concatenate 6 | from keras.layers import add 7 | from Models.DBlayers.Attention import CAM,PAM 8 | from tensorflow.keras import backend as K 9 | 10 | 11 | 12 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 13 | 14 | def conv3x3(x, out_filters, strides=(1, 1)): 15 | x = Conv2D(out_filters, 3, padding='same', strides=strides, use_bias=False, kernel_initializer='he_normal')(x) 16 | return x 17 | 18 | 19 | def Conv2d_BN(x, nb_filter, kernel_size, strides=(1, 1), padding='same', use_activation=True): 20 | x = Conv2D(nb_filter, kernel_size, padding=padding, strides=strides, kernel_initializer='he_normal')(x) 21 | x = BatchNormalization(axis=3)(x) 22 | if use_activation: 23 | x = Activation('relu')(x) 24 | return x 25 | else: 26 | return x 27 | 28 | 29 | def basic_Block(input, out_filters, strides=(1, 1), with_conv_shortcut=False): 30 | x = conv3x3(input, out_filters, strides) 31 | x = BatchNormalization(axis=3)(x) 32 | x = Activation('relu')(x) 33 | 34 | x = conv3x3(x, out_filters) 35 | x = BatchNormalization(axis=3)(x) 36 | 37 | if with_conv_shortcut: 38 | residual = Conv2D(out_filters, 1, strides=strides, use_bias=False, kernel_initializer='he_normal')(input) 39 | residual = BatchNormalization(axis=3)(residual) 40 | x = add([x, residual]) 41 | else: 42 | x = add([x, input]) 43 | 44 | x = Activation('relu')(x) 45 | return x 46 | 47 | 48 | def bottleneck_Block(input, out_filters, strides=(1, 1), dilation=(1, 1), with_conv_shortcut=False): 49 | expansion = 4 50 | de_filters = int(out_filters / expansion) 51 | 52 | x = Conv2D(de_filters, 1, use_bias=False, kernel_initializer='he_normal')(input) 53 | x = BatchNormalization(axis=3)(x) 54 | x = Activation('relu')(x) 55 | 56 | x = Conv2D(de_filters, 3, strides=strides, padding='same', 57 | dilation_rate=dilation, use_bias=False, kernel_initializer='he_normal')(x) 58 | x = BatchNormalization(axis=3)(x) 59 | x = Activation('relu')(x) 60 | 61 | x = Conv2D(out_filters, 1, use_bias=False, kernel_initializer='he_normal')(x) 62 | x = BatchNormalization(axis=3)(x) 63 | 64 | if with_conv_shortcut: 65 | residual = Conv2D(out_filters, 1, strides=strides, use_bias=False, kernel_initializer='he_normal')(input) 66 | residual = BatchNormalization(axis=3)(residual) 67 | x = add([x, residual]) 68 | else: 69 | x = add([x, input]) 70 | 71 | x = Activation('relu')(x) 72 | return x 73 | 74 | 75 | def danet_resnet101(height, width, channel, classes): 76 | input = Input(shape=(height, width, channel)) 77 | 78 | conv1_1 = Conv2D(64, 7, strides=(2, 2), padding='same', use_bias=False, kernel_initializer='he_normal')(input) 79 | conv1_1 = BatchNormalization(axis=3)(conv1_1) 80 | conv1_1 = Activation('relu')(conv1_1) 81 | conv1_2 = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(conv1_1) 82 | 83 | # conv2_x 1/4 84 | conv2_1 = bottleneck_Block(conv1_2, 256, strides=(1, 1), with_conv_shortcut=True) 85 | conv2_2 = bottleneck_Block(conv2_1, 256) 86 | conv2_3 = bottleneck_Block(conv2_2, 256) 87 | 88 | # conv3_x 1/8 89 | conv3_1 = bottleneck_Block(conv2_3, 512, strides=(2, 2), with_conv_shortcut=True) 90 | conv3_2 = bottleneck_Block(conv3_1, 512) 91 | conv3_3 = bottleneck_Block(conv3_2, 512) 92 | conv3_4 = bottleneck_Block(conv3_3, 512) 93 | 94 | # conv4_x 1/16 95 | conv4_1 = bottleneck_Block(conv3_4, 1024, strides=(1, 1), dilation=(2, 2), with_conv_shortcut=True) 96 | conv4_2 = bottleneck_Block(conv4_1, 1024, dilation=(2, 2)) 97 | conv4_3 = bottleneck_Block(conv4_2, 1024, dilation=(2, 2)) 98 | conv4_4 = bottleneck_Block(conv4_3, 1024, dilation=(2, 2)) 99 | conv4_5 = bottleneck_Block(conv4_4, 1024, dilation=(2, 2)) 100 | conv4_6 = bottleneck_Block(conv4_5, 1024, dilation=(2, 2)) 101 | conv4_7 = bottleneck_Block(conv4_6, 1024, dilation=(2, 2)) 102 | conv4_8 = bottleneck_Block(conv4_7, 1024, dilation=(2, 2)) 103 | conv4_9 = bottleneck_Block(conv4_8, 1024, dilation=(2, 2)) 104 | conv4_10 = bottleneck_Block(conv4_9, 1024, dilation=(2, 2)) 105 | conv4_11 = bottleneck_Block(conv4_10, 1024, dilation=(2, 2)) 106 | conv4_12 = bottleneck_Block(conv4_11, 1024, dilation=(2, 2)) 107 | conv4_13 = bottleneck_Block(conv4_12, 1024, dilation=(2, 2)) 108 | conv4_14 = bottleneck_Block(conv4_13, 1024, dilation=(2, 2)) 109 | conv4_15 = bottleneck_Block(conv4_14, 1024, dilation=(2, 2)) 110 | conv4_16 = bottleneck_Block(conv4_15, 1024, dilation=(2, 2)) 111 | conv4_17 = bottleneck_Block(conv4_16, 1024, dilation=(2, 2)) 112 | conv4_18 = bottleneck_Block(conv4_17, 1024, dilation=(2, 2)) 113 | conv4_19 = bottleneck_Block(conv4_18, 1024, dilation=(2, 2)) 114 | conv4_20 = bottleneck_Block(conv4_19, 1024, dilation=(2, 2)) 115 | conv4_21 = bottleneck_Block(conv4_20, 1024, dilation=(2, 2)) 116 | conv4_22 = bottleneck_Block(conv4_21, 1024, dilation=(2, 2)) 117 | conv4_23 = bottleneck_Block(conv4_22, 1024, dilation=(2, 2)) 118 | 119 | # conv5_x 1/32 120 | conv5_1 = bottleneck_Block(conv4_23, 2048, strides=(1, 1), dilation=(4, 4), with_conv_shortcut=True) 121 | conv5_2 = bottleneck_Block(conv5_1, 2048, dilation=(4, 4)) 122 | conv5_3 = bottleneck_Block(conv5_2, 2048, dilation=(4, 4)) 123 | 124 | # ATTENTION 125 | reduce_conv5_3 = Conv2D(512, 3, padding='same', use_bias=False, kernel_initializer='he_normal')(conv5_3) 126 | reduce_conv5_3 = BatchNormalization(axis=3)(reduce_conv5_3) 127 | reduce_conv5_3 = Activation('relu')(reduce_conv5_3) 128 | 129 | pam = PAM()(reduce_conv5_3) 130 | pam = Conv2D(512, 3, padding='same', use_bias=False, kernel_initializer='he_normal')(pam) 131 | pam = BatchNormalization(axis=3)(pam) 132 | pam = Activation('relu')(pam) 133 | pam = Dropout(0.5)(pam) 134 | pam = Conv2D(512, 3, padding='same', use_bias=False, kernel_initializer='he_normal')(pam) 135 | 136 | cam = CAM()(reduce_conv5_3) 137 | cam = Conv2D(512, 3, padding='same', use_bias=False, kernel_initializer='he_normal')(cam) 138 | cam = BatchNormalization(axis=3)(cam) 139 | cam = Activation('relu')(cam) 140 | cam = Dropout(0.5)(cam) 141 | cam = Conv2D(512, 3, padding='same', use_bias=False, kernel_initializer='he_normal')(cam) 142 | 143 | feature_sum = add([pam, cam]) 144 | feature_sum = Dropout(0.5)(feature_sum) 145 | feature_sum = Conv2d_BN(feature_sum, 512, 1) 146 | merge7 = concatenate([conv3_4, feature_sum], axis=3) 147 | conv7 = Conv2d_BN(merge7, 512, 3) 148 | conv7 = Conv2d_BN(conv7, 512, 3) 149 | 150 | up8 = Conv2d_BN(UpSampling2D(size=(2, 2))(conv7), 256, 2) 151 | merge8 = concatenate([conv2_3, up8], axis=3) 152 | conv8 = Conv2d_BN(merge8, 256, 3) 153 | conv8 = Conv2d_BN(conv8, 256, 3) 154 | 155 | up9 = Conv2d_BN(UpSampling2D(size=(2, 2))(conv8), 64, 2) 156 | merge9 = concatenate([conv1_1, up9], axis=3) 157 | conv9 = Conv2d_BN(merge9, 64, 3) 158 | conv9 = Conv2d_BN(conv9, 64, 3) 159 | 160 | up10 = Conv2d_BN(UpSampling2D(size=(2, 2))(conv9), 64, 2) 161 | conv10 = Conv2d_BN(up10, 64, 3) 162 | conv10 = Conv2d_BN(conv10, 64, 3) 163 | 164 | conv11 = Conv2d_BN(conv10, classes, 1, use_activation=None) 165 | activation = Activation('sigmoid', name='Classification')(conv11) 166 | 167 | model = Model(inputs=input, outputs=activation) 168 | return model 169 | 170 | 171 | -------------------------------------------------------------------------------- /Preprocess/DFactionSeg.py: -------------------------------------------------------------------------------- 1 | import math 2 | import h5py 3 | import pandas as pd 4 | import numpy as np 5 | import tsaug 6 | from sklearn import preprocessing 7 | import scipy.signal as signal 8 | import nina_funcs as nf 9 | from sklearn.preprocessing import StandardScaler 10 | from tqdm import tqdm 11 | 12 | 13 | train_reps = [1, 3, 4, 6] 14 | test_reps = [2, 5] 15 | gestures = list(range(1, 50)) 16 | 17 | ''' 18 | 本类将上一个实验的预处理部分用dataframe格式重写,便于后续实验在 19 | 数据处理上共用,也是更符合github工具包的存储格式 20 | ''' 21 | ''' df形式的动作分割(要求能不排除休息状态)''' 22 | def action_reseg(data, channel, endlabel): 23 | actionList = [] # 存储动作 24 | begin = 0 25 | count = 0 # 用于动作计数,纠正rep标签 26 | for aim in tqdm(range(1, len(data))): 27 | # 控制手势停止时间 28 | if (data.iloc[aim, channel] == endlabel + 1): 29 | break 30 | if (aim == len(data) - 1 or data.iloc[aim, channel] != data.iloc[aim - 1, channel]): 31 | end = aim 32 | rep_num = set(data.iloc[begin:end, channel + 1]) 33 | show = data.iloc[begin:end, :] 34 | if (data.iloc[begin, channel + 1] != math.floor((count % 12) / 2) + 1 or len(rep_num) != 1): 35 | count1 = math.floor((count % 12) / 2)+1 36 | data.loc[list(range(begin, end)), 'rerepetition'] = [count1 for _ in range(begin, end)] 37 | count = count + 1 38 | actionList.append(data[begin:end]) 39 | begin = end 40 | return actionList 41 | 42 | 43 | def action_seg(data, channel, endlabel): 44 | actionList = [] # 存储动作 45 | begin = 0 46 | count = 0 # 用于动作计数,纠正rep标签 47 | for aim in tqdm(range(1, len(data))): 48 | # 控制手势停止时间 49 | if (data.iloc[aim, channel] == endlabel + 1): 50 | break 51 | if (aim == len(data) - 1 or data.iloc[aim, channel] != data.iloc[aim - 1, channel]): 52 | end = aim 53 | rep_num = set(data.iloc[begin:end, channel + 1]) 54 | show = data.iloc[begin:end, :] 55 | if (data.iloc[begin, channel + 1] != math.floor((count % 12) / 2) + 1 or len(rep_num) != 1): 56 | count1 = math.floor((count % 12) / 2)+1 57 | data.loc[list(range(begin, end)), 'repetition'] = [count1 for _ in range(begin, end)] 58 | count = count + 1 59 | actionList.append(data[begin:end]) 60 | begin = end 61 | return actionList 62 | 63 | '''数据标准化(list的元素为df的方式)''' 64 | def uniform(actionList, channel): 65 | for action in actionList: 66 | iemg = action.iloc[:, :channel].copy() 67 | scaler = preprocessing.StandardScaler() 68 | BNemg = scaler.fit_transform(iemg) 69 | action = action.copy(False) 70 | action.iloc[:, :channel] = BNemg 71 | 72 | return actionList 73 | 74 | 75 | ''' 76 | 该函数在输入二维数组时会将各个通道随机打乱,破坏了不同电极采样的同步性,故设定随机种子,单个通道依次打乱 77 | 输入的数据是一维列向量,新生成的数据是一维行向量 78 | ''' 79 | def OneEnhanceEMG(data): 80 | newdata =tsaug.TimeWarp(n_speed_change=1, max_speed_ratio=1.5, seed=123).augment(data) 81 | # enhancedata =np.hstack((data, newdata)) 82 | return data, newdata 83 | 84 | 85 | 86 | ''' 87 | 将数据增强写在标准化里面是为了将增强的数据和原始数据分开标准化,拼接的标准化方法会影响原始数据。 88 | 不分割为肌电子图返回数据标准化后结果,BNdatalist元素为单独一个动作手势标准化后的结果, 89 | 保存有对应的标签 ,返回类型(time,channel),考虑到实验流程,把数据增强放在标准化前 90 | ''' 91 | 92 | def bnEnhancesegment(seglist, channel=12): 93 | channel = 12 94 | BNdatalist = [] 95 | for i in range(len(seglist)): 96 | temp_label = seglist[i].iloc[0, channel] 97 | temp_rep = seglist[i].iloc[0, channel + 1] 98 | # 跳过标签为0 99 | if (temp_label == 0): 100 | continue 101 | if temp_rep in ([1, 3, 4, 6]): 102 | # 增强前后的手势分开标准化,对训练集第1,3,4,6次进行增强 103 | timedata = np.array(seglist[i].iloc[:, :channel].copy()) 104 | data = [] 105 | newdata = [] 106 | for Numchannel in range(12): 107 | datasample, newdatasample = OneEnhanceEMG(timedata[:, Numchannel]) 108 | data.append(datasample) 109 | newdata.append(newdatasample) 110 | data = (np.array(data)).T # 将数据转换为(time,channel) 111 | newdata = (np.array(newdata)).T 112 | # flag来控制对未增强数据的保存 113 | flag = True 114 | for iemg in ([data, newdata]): 115 | scaler = StandardScaler() 116 | Zscdata = scaler.fit_transform(iemg[:]) 117 | BNdata = Zscdata 118 | if (flag): 119 | bndata1 = BNdata 120 | flag = False 121 | else: 122 | bndata2 = BNdata 123 | # 数据倍增后,标签倍增 124 | BNdata = np.vstack((bndata1, bndata2)) 125 | BNlabel = np.hstack([seglist[i].iloc[:, channel], seglist[i].iloc[:, channel]]) 126 | BNrep = np.hstack([seglist[i].iloc[:, channel + 1], seglist[i].iloc[:, channel + 1]]) 127 | # 测试集不做数据增强 128 | else: 129 | iemg = np.array(seglist[i].iloc[:, :channel].copy()) 130 | scaler = StandardScaler() 131 | Zscdata = scaler.fit_transform(iemg[:]) 132 | BNdata = Zscdata 133 | BNlabel = np.array(seglist[i].iloc[:, channel]) 134 | BNrep = np.array(seglist[i].iloc[:, channel + 1]) 135 | myemg = pd.DataFrame(BNdata) 136 | myemg['stimulus'] = BNlabel 137 | myemg['repetition'] = BNrep 138 | BNdatalist.append(myemg) 139 | return BNdatalist 140 | 141 | 142 | '''时间增量窗口分割和划分数据集,输入参数为存储动作的list''' 143 | 144 | 145 | def action_comb(actionList, timeWindow, strideWindow, channel=12): 146 | emgList = [[], [], [], [], [], [], []] 147 | labelList = [[], [], [], [], [], [], []] 148 | repList = [[], [], [], [], [], [], []] 149 | for action in actionList: 150 | rep = int(action.values[0, channel + 1]) 151 | stimulus = int(action.values[0, channel]) 152 | if rep == 0 or stimulus==0: # 暂时不考虑休息状态 153 | continue 154 | length = math.floor((len(action) - timeWindow) / strideWindow) + 1 155 | for j in range(length): 156 | subImage = action.iloc[strideWindow * j:strideWindow * j + timeWindow, 0:channel] # 连续分割方式 157 | emgList[rep].append(subImage) 158 | labelList[rep].append(action.iloc[0, channel]) 159 | repList[rep].append(action.iloc[0, channel + 1]) 160 | 161 | for i in range(len(emgList)): 162 | emgList[i] = np.array(emgList[i]) 163 | for i in range(len(labelList)): 164 | labelList[i] = np.array(labelList[i]) 165 | for i in range(len(repList)): 166 | repList[i] = np.array(repList[i]) 167 | 168 | return emgList, labelList, repList 169 | 170 | 171 | root_data = 'D:/Pengxiangdong/ZX/' 172 | 173 | for j in range(7, 41): 174 | df = pd.read_hdf(root_data+'DB2/data/restimulus/refilter/DB2_s' + str(j) + 'filter.h5', 'df') 175 | 176 | '''滑动窗口分割''' 177 | actionList = action_reseg(df, 12, 49) 178 | # bnList= uniform(actionList,12) 179 | bnList = bnEnhancesegment(actionList, 12) 180 | emgList, labelList, repList = action_comb(bnList, 400, 100) 181 | 182 | emg = np.concatenate([emgList[1], emgList[2], emgList[3], emgList[4], emgList[5], emgList[6]], axis=0) 183 | label = np.concatenate([labelList[1], labelList[2], labelList[3], labelList[4], labelList[5], labelList[6]], axis=0) 184 | rep = np.concatenate([repList[1], repList[2], repList[3], repList[4], repList[5], repList[6], ], axis=0) 185 | 186 | # # 存储为h5文件 187 | file = h5py.File(root_data + 'DB2/data/restimulus/reSegEnhance/DB2_s' + str(j) + 'SegEnhance.h5', 'w') 188 | file.create_dataset('emg', data=(emg).astype('float32')) 189 | file.create_dataset('label', data=(label).astype('int')) 190 | file.create_dataset('rep', data=(rep).astype('int')) 191 | file.close() 192 | print('******************DB2_s' + str(j) + '分割完成***********************') 193 | 194 | -------------------------------------------------------------------------------- /Preprocess/EnhanceZsc.py: -------------------------------------------------------------------------------- 1 | import math 2 | from copy import deepcopy 3 | import h5py 4 | import numpy as np 5 | from sklearn import preprocessing 6 | import EMGImg 7 | import tsaug 8 | from pyts.image import MarkovTransitionField, GramianAngularField 9 | from Util.feature_utils import featureRMS, featureMAV, featureWL, featureZC, featureSSC 10 | 11 | 12 | def OneEnhanceEMG(data): 13 | # data =data.T #需要把数据转换成(channel,time) 14 | newdata =tsaug.TimeWarp(n_speed_change=1, max_speed_ratio=1.5, seed=123).augment(data) 15 | # enhancedata =np.hstack((data, newdata)) 16 | return data, newdata 17 | 18 | 19 | ''' 20 | Step1: 按动作次数将手势分割(数据,手势类别,标签通道数) 21 | ''' 22 | def actionSeg(data, dataclass, channel): 23 | data = np.array(data) 24 | Datalist = [] 25 | for j in range(1, dataclass + 1): 26 | num = 0 27 | while (num < 6): 28 | for i in range(len(data)): 29 | if data[i, channel] == j: # alldata最后一维存储标签 30 | start = i 31 | break 32 | for k in range(start, len(data)): 33 | if data[k, channel] == 0: 34 | end = k - 1 35 | break 36 | if k == len(data) - 1: 37 | end = len(data) - 1 38 | break 39 | 40 | print(start, end) 41 | num = num + 1 42 | emg = (deepcopy(data[start:end, 0:channel])) 43 | label = (deepcopy(data[start:end, channel])) 44 | rep = (deepcopy(data[start:end, channel + 1])) 45 | myemg = EMGImg.reEMG(emg, label, rep) 46 | Datalist.append(myemg) # 用append将每次动作分割为单独的元素,保存了emg数据和标签 47 | for m in range(start, end + 1): 48 | data[m, channel] = 100 49 | return Datalist # 返回数据为list类型,保存不同长度的数据 50 | 51 | 52 | 53 | '''Step2: 只做数据增强''' 54 | def EnhanceSeg(seglist): 55 | channel = 12 56 | Endatalist = [] 57 | for i in range(len(seglist)): 58 | data = [] 59 | newdata = [] 60 | rep =(seglist[i].rep)[0] 61 | if rep in ([1, 3, 4, 6]): # 增强前后的手势分开标准化,对训练集第1,3,4,6次进行增强 62 | for k in range(channel): 63 | tempdata=seglist[i].data 64 | datasample, newdatasample = OneEnhanceEMG(tempdata[:, k]) 65 | data.append(datasample) 66 | newdata.append(newdatasample) 67 | data = (np.array(data)).T 68 | newdata = (np.array(newdata)).T 69 | Endata = np.vstack((data, newdata)) 70 | Enlabel = np.hstack((seglist[i].label, seglist[i].label)) 71 | Enrep = np.hstack((seglist[i].rep, seglist[i].rep)) 72 | 73 | else: 74 | Endata = seglist[i].data 75 | Enlabel= seglist[i].label 76 | Enrep = seglist[i].rep 77 | myemg = EMGImg.reEMG(Endata, Enlabel,Enrep) 78 | Endatalist.append(myemg) 79 | return Endatalist 80 | 81 | 82 | 83 | ''' 84 | Step3: 分割为肌电子图 85 | ''' 86 | def creatimg(segList): 87 | Datalist = [] #存放每个动作的emg对象 88 | imageLength = 400 89 | stridewindow = 100 90 | for i in range(len(segList)): 91 | # 构造肌电子图并将信号放大到伏特级别 92 | BNdata = (segList[i].data) 93 | length = math.floor((BNdata.shape[0] - imageLength) / stridewindow) + 1 94 | for j in range(length): 95 | emg2 = BNdata[stridewindow * j:stridewindow * j + imageLength, :] 96 | label2 = int(segList[i].label[0]) - 1 97 | rep2 =(segList[i].rep[0]) 98 | myemg = EMGImg.reEMG(emg2, label2, rep2) 99 | Datalist.append(myemg) 100 | 101 | return Datalist 102 | 103 | #特征图拼接方法 104 | def feaimg(segList): 105 | Datalist = [] #存放每个动作的emg对象 106 | imageLength = 20 107 | stridewindow = 1 108 | for i in range(len(segList)): 109 | # 考虑构造肌电子图并将信号放大到伏特级别 110 | iemg = (segList[i].data)*1e6 111 | length = math.floor((iemg.shape[0] - imageLength) / stridewindow) + 1 112 | for j in range(length): 113 | rms = featureRMS(iemg[stridewindow * j:stridewindow * j + imageLength, :]) 114 | mav = featureMAV(iemg[stridewindow * j:stridewindow * j + imageLength, :]) 115 | wl = featureWL(iemg[stridewindow * j:stridewindow * j + imageLength, :]) 116 | zc = featureZC(iemg[stridewindow * j:stridewindow * j + imageLength, :]) 117 | ssc = featureSSC(iemg[stridewindow * j:stridewindow * j + imageLength, :]) 118 | featureStack = np.hstack((rms, mav, wl, zc, ssc)) 119 | emg2 = featureStack # 连续分割方式 120 | label2 = int(segList[i].label[0]) - 1 121 | rep2 = (segList[i].rep[0]) 122 | myemg = EMGImg.reEMG(emg2, label2, rep2) 123 | Datalist.append(myemg) 124 | return Datalist 125 | 126 | 127 | 128 | def GASF(segList): 129 | Datalist = [] # 存放每个动作的emg对象 130 | imageLength = 20 131 | stridewindow = 1 132 | for i in range(len(segList)): 133 | # 考虑构造肌电子图并将信号放大到伏特级别 134 | BNdata = (segList[i].data) 135 | length = math.floor((BNdata.shape[0] - imageLength) / stridewindow) + 1 136 | for j in range(length): 137 | emg = BNdata[stridewindow * j:stridewindow * j + imageLength, :] # 连续分割方式 138 | gasf = GramianAngularField(image_size=10, method='summation') 139 | emg2 = gasf.fit_transform(emg) 140 | label2 = int(segList[i].label[0]) - 1 141 | rep2 = (segList[i].rep[0]) 142 | myemg = EMGImg.reEMG(emg2, label2, rep2) 143 | Datalist.append(myemg) 144 | return Datalist 145 | 146 | 147 | '''Step4: 数据归一化''' 148 | def uniform(seglist,basis): 149 | channel = 12 150 | Datalist = [] 151 | for i in range(len(seglist)): 152 | iemg = seglist[i].data 153 | emg2 = basis.transform(iemg) 154 | label2 = seglist[i].label 155 | rep2 = (seglist[i].rep) 156 | myemg = EMGImg.reEMG(emg2, label2, rep2) 157 | Datalist.append(myemg) 158 | return Datalist 159 | 160 | 161 | '''Step5: 数据集划分''' 162 | def getdata(seglist): 163 | emglist = [[], [], [], [], [], []] 164 | labellist = [[], [], [], [], [], []] 165 | for i in range(len(seglist)): 166 | for j in ([1, 2, 3, 4, 5, 6]): 167 | if (seglist[i].rep) == j: 168 | emglist[j - 1].append(seglist[i].data) 169 | labellist[j - 1].append(seglist[i].label) 170 | # 按重复次数分布存入对应数组 171 | for i in range(len(emglist)): 172 | emglist[i] = np.array(emglist[i]) 173 | for i in range(len(labellist)): 174 | labellist[i] = np.array(labellist[i]) 175 | 176 | return emglist, labellist 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | if __name__ == '__main__': 185 | for j in range(1, 2): 186 | h5 = h5py.File('F:/DB2/filter/DB2_s' + str(j) + 'filter.h5', 'r') 187 | alldata = h5['alldata'][:] 188 | #对所有数据归一化,得到均值 189 | basis = preprocessing.MinMaxScaler().fit(alldata[:, 0:12]) 190 | #动作状态数据分割 肌电子图标准化 191 | actionlist = actionSeg(alldata, 49, 12) 192 | # Enhancelist = EnhanceSeg(actionlist) 193 | imglist = creatimg(actionlist) 194 | unilist = uniform(imglist, basis) 195 | datalist, labellist= getdata(unilist) 196 | 197 | 198 | file = h5py.File('F:/DB2/Part/DB2_s' + str(j) + 'Seg.h5', 'w') 199 | 200 | file.create_dataset('Data0', data=(datalist[0]).astype('float32')) 201 | file.create_dataset('Data1', data=(datalist[1]).astype('float32')) 202 | file.create_dataset('Data2', data=(datalist[2]).astype('float32')) 203 | file.create_dataset('Data3', data=(datalist[3]).astype('float32')) 204 | file.create_dataset('Data4', data=(datalist[4]).astype('float32')) 205 | file.create_dataset('Data5', data=(datalist[5]).astype('float32')) 206 | file.create_dataset('label0', data=(labellist[0]).astype('int32')) 207 | file.create_dataset('label1', data=(labellist[1]).astype('int32')) 208 | file.create_dataset('label2', data=(labellist[2]).astype('int32')) 209 | file.create_dataset('label3', data=(labellist[3]).astype('int32')) 210 | file.create_dataset('label4', data=(labellist[4]).astype('int32')) 211 | file.create_dataset('label5', data=(labellist[5]).astype('int32')) 212 | file.close() 213 | print('******************DB2_s' + str(j) + '分割完成***********************') 214 | -------------------------------------------------------------------------------- /Models/DBEmgNet/Away3CBAMNEW.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import backend as K 3 | from tensorflow.keras import layers as KL 4 | from tensorflow.keras.layers import * 5 | 6 | channel_axis = 1 if K.image_data_format() == "channels_first" else 3 7 | 8 | 9 | # CAM 特征通道注意力 10 | def channel_attention(input_xs, reduction_ratio=0.125): 11 | # get channel 12 | channel = int(input_xs.shape[channel_axis]) 13 | maxpool_channel = GlobalMaxPooling2D()(input_xs) 14 | maxpool_channel = Reshape((1, 1, channel))(maxpool_channel) 15 | avgpool_channel = GlobalAvgPool2D()(input_xs) 16 | avgpool_channel = Reshape((1, 1, channel))(avgpool_channel) 17 | Dense_One = Dense(units=int(channel * reduction_ratio), activation='relu', kernel_initializer='he_normal', 18 | use_bias=True, bias_initializer='zeros') 19 | Dense_Two = Dense(units=int(channel), activation='relu', kernel_initializer='he_normal', use_bias=True, 20 | bias_initializer='zeros') 21 | # max path 22 | mlp_1_max = Dense_One(maxpool_channel) 23 | mlp_2_max = Dense_Two(mlp_1_max) 24 | mlp_2_max = Reshape(target_shape=(1, 1, int(channel)))(mlp_2_max) 25 | # avg path 26 | mlp_1_avg = Dense_One(avgpool_channel) 27 | mlp_2_avg = Dense_Two(mlp_1_avg) 28 | mlp_2_avg = Reshape(target_shape=(1, 1, int(channel)))(mlp_2_avg) 29 | channel_attention_feature = Add()([mlp_2_max, mlp_2_avg]) 30 | channel_attention_feature = Activation('sigmoid')(channel_attention_feature) 31 | return Multiply()([channel_attention_feature, input_xs]) 32 | 33 | 34 | # # SAM 空间注意力 35 | # def spatial_attention(channel_refined_feature): 36 | # maxpool_spatial = Lambda(lambda x: K.max(x, axis=3, keepdims=True))(channel_refined_feature) 37 | # avgpool_spatial = Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(channel_refined_feature) 38 | # max_avg_pool_spatial = Concatenate(axis=3)([maxpool_spatial, avgpool_spatial]) 39 | # return Conv2D(filters=1, kernel_size=(2, 2), padding="same", activation='sigmoid', 40 | # kernel_initializer='he_normal', use_bias=False)(max_avg_pool_spatial) 41 | 42 | # 时间注意力 43 | def time_attention(channel_refined_feature): 44 | maxpool_spatial = Lambda(lambda x: K.max(x, axis=3, keepdims=True))(channel_refined_feature) 45 | avgpool_spatial = Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(channel_refined_feature) 46 | max_avg_pool_spatial = Concatenate(axis=3)([maxpool_spatial, avgpool_spatial]) 47 | return Conv2D(filters=1, kernel_size=(2, 1), padding="same", activation='sigmoid', 48 | kernel_initializer='he_normal', use_bias=False)(max_avg_pool_spatial) 49 | 50 | 51 | # Acquisition channel 采集通道注意力 52 | def acquisition_attention(channel_refined_feature): 53 | maxpool_spatial = Lambda(lambda x: K.max(x, axis=3, keepdims=True))(channel_refined_feature) 54 | avgpool_spatial = Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(channel_refined_feature) 55 | max_avg_pool_spatial = Concatenate(axis=3)([maxpool_spatial, avgpool_spatial]) 56 | return Conv2D(filters=1, kernel_size=(1, 2), padding="same", activation='sigmoid', 57 | kernel_initializer='he_normal', use_bias=False)(max_avg_pool_spatial) 58 | 59 | ''' 60 | # 标准的CBAM,没有卷积!!!加入ResBlock 61 | def cbam_module(input_xs, reduction_ratio=0.5): 62 | channel_refined_feature = channel_attention(input_xs, reduction_ratio=reduction_ratio) 63 | spatial_attention_feature = spatial_attention(channel_refined_feature) 64 | refined_feature = Multiply()([channel_refined_feature, spatial_attention_feature]) 65 | return Add()([refined_feature, input_xs]) 66 | ''' 67 | 68 | 69 | # 加入ResBlock 采集通道注意力机制 70 | def cbam_acquisition(input_xs, reduction_ratio=0.5): 71 | channel_refined_feature = channel_attention(input_xs, reduction_ratio=reduction_ratio) 72 | acquisition_attention_feature = acquisition_attention(channel_refined_feature) 73 | refined_feature = Multiply()([channel_refined_feature, acquisition_attention_feature]) 74 | return Add()([refined_feature, input_xs]) 75 | # 标准的CBAM,没有卷积!!!加入ResBlock 76 | def cbam_time(input_xs, reduction_ratio=0.5): 77 | channel_refined_feature = channel_attention(input_xs, reduction_ratio=reduction_ratio) 78 | time_attention_feature = time_attention(channel_refined_feature) 79 | refined_feature = Multiply()([channel_refined_feature, time_attention_feature]) 80 | return Add()([refined_feature, input_xs]) 81 | 82 | 83 | 84 | # 3条支路,每个支路做串行的卷积注意力,在网络层加入标准化,注意顺序,早期网络加入1×1卷积 85 | def Away3reluBNCBAMcatNEW(): 86 | input1 = Input(shape=(400, 8)) 87 | input11 = tf.expand_dims(input=input1, axis=3) 88 | input2 = Input(shape=(400, 2)) 89 | input21 = tf.expand_dims(input=input2, axis=3) 90 | input3 = Input(shape=(400, 2)) 91 | input31 = tf.expand_dims(input=input3, axis=3) 92 | #早期融合网络,加入1×1卷积 93 | c1 = Concatenate(axis=-2)([input11, input21, input31]) 94 | c1 = Conv2D(filters=32, kernel_size=(1, 1), strides=(1, 1), activation='relu', padding='same')(c1) 95 | 96 | 97 | x1 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input11) 98 | x1 = Activation('relu')(x1) 99 | x1 = BatchNormalization()(x1) 100 | x1 = cbam_time(x1) 101 | x1 = Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), padding='same')(x1) 102 | x1 = Activation('relu')(x1) 103 | x1 = BatchNormalization()(x1) 104 | output1 = cbam_acquisition(x1) 105 | 106 | 107 | x2 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input21) 108 | x2 = Activation('relu')(x2) 109 | x2 = BatchNormalization()(x2) 110 | x2 = cbam_time(x2) 111 | x2 = Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), padding='same')(x2) 112 | x2 = Activation('relu')(x2) 113 | x2 = BatchNormalization()(x2) 114 | output2 = cbam_acquisition(x2) 115 | 116 | 117 | x3 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), padding='same')(input31) 118 | x3 = Activation('relu')(x3) 119 | x3 = BatchNormalization()(x3) 120 | x3 = cbam_time(x3) 121 | x3 = Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), padding='same')(x3) 122 | x3 = Activation('relu')(x3) 123 | x3 = BatchNormalization()(x3) 124 | output3 = cbam_acquisition(x3) 125 | 126 | 127 | c2 = Concatenate(axis=-2)([output1, output2, output3]) 128 | c = Concatenate(axis=-1)([c1, c2]) 129 | X = GlobalAvgPool2D()(c) 130 | X = Dense(128, activation='relu')(X) 131 | X = Dropout(0.1)(X) 132 | s = Dense(49, activation='softmax')(X) 133 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 134 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 135 | loss='categorical_crossentropy', metrics=['accuracy']) 136 | return model 137 | 138 | 139 | 140 | 141 | def Away3reluBNCBAMsoft(): 142 | input1 = Input(shape=(400, 8)) 143 | input11 = tf.expand_dims(input=input1, axis=3) 144 | input2 = Input(shape=(400, 2)) 145 | input21 = tf.expand_dims(input=input2, axis=3) 146 | input3 = Input(shape=(400, 2)) 147 | input31 = tf.expand_dims(input=input3, axis=3) 148 | #早期融合网络,加入1×1卷积 149 | c1 = Concatenate(axis=-2)([input11, input21, input31]) 150 | c1 = Conv2D(filters=32, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(c1) 151 | 152 | 153 | x1 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input11) 154 | x1 = BatchNormalization()(x1) 155 | x1 = cbam_time(x1) 156 | x1 = Conv2D(filters=128, kernel_size=(1, 8), strides=(1, 1), activation='relu', padding='same')(x1) 157 | x1 = BatchNormalization()(x1) 158 | output1 = cbam_acquisition(x1) 159 | 160 | 161 | x2 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input21) 162 | x2 = BatchNormalization()(x2) 163 | x2 = cbam_time(x2) 164 | x2 = Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x2) 165 | x2 = BatchNormalization()(x2) 166 | output2 = cbam_acquisition(x2) 167 | 168 | 169 | x3 = Conv2D(filters=64, kernel_size=(8, 1), strides=(1, 1), activation='relu', padding='same')(input31) 170 | x3 = BatchNormalization()(x3) 171 | x3 = cbam_time(x3) 172 | x3 = Conv2D(filters=128, kernel_size=(1, 2), strides=(1, 1), activation='relu', padding='same')(x3) 173 | x3 = BatchNormalization()(x3) 174 | output3 = cbam_acquisition(x3) 175 | 176 | 177 | c2 = Concatenate(axis=-2)([output1, output2, output3]) 178 | c = Concatenate(axis=-1)([c1, c2]) 179 | X = GlobalAvgPool2D()(c) 180 | X = Dense(512, activation='relu')(X) 181 | X = Dropout(0.1)(X) 182 | s = Dense(49, activation='softmax')(X) 183 | model = tf.keras.Model(inputs=[input1, input2, input3], outputs=s) 184 | model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001), 185 | loss='categorical_crossentropy', metrics=['accuracy']) 186 | return model 187 | 188 | 189 | -------------------------------------------------------------------------------- /nina_fun.txt: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | from sklearn.model_selection import train_test_split, StratifiedKFold 4 | from sklearn.preprocessing import StandardScaler 5 | from scipy import signal 6 | from scipy.io import loadmat 7 | from sklearn.metrics import confusion_matrix 8 | import os 9 | import pywt 10 | from tensorflow.keras.models import Sequential, Model, load_model 11 | import datetime 12 | from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint 13 | from tensorflow import keras as K 14 | from tqdm import tqdm 15 | from sklearn.decomposition import PCA 16 | import scipy as sp 17 | 18 | 19 | # DWPT分解 20 | def emg_dwpt(signal, wavelet_name='db1'): 21 | wavelet_level = int(np.log2(len(signal))) 22 | wp = pywt.WaveletPacket(signal, wavelet_name, mode='sym') 23 | coeffs = [] 24 | level_coeff = wp.get_level(wavelet_level) 25 | for i in range(len(level_coeff)): 26 | coeffs.append(level_coeff[i].data) 27 | coeffs = np.array(coeffs) 28 | coeffs = coeffs.flatten() 29 | return coeffs 30 | 31 | 32 | def fft(data): 33 | return np.fft.fft(data) 34 | 35 | 36 | def psd(data): 37 | return np.abs(np.fft.fft(data)) ** 2 38 | 39 | 40 | ''' ---时间域的特征分隔线--- ''' 41 | 42 | 43 | def mav(data): 44 | return np.mean(np.abs(data)) 45 | 46 | 47 | def iemg(data): 48 | return np.sum(np.abs(data)) 49 | 50 | 51 | def wl(data): 52 | return np.sum(abs(np.diff(data))) 53 | 54 | 55 | def rms(data): 56 | return np.sqrt(np.mean(data ** 2)) 57 | 58 | 59 | def hist(data, nbins=20): 60 | histsig, bin_edges = np.histogram(data, bins=nbins) 61 | return tuple(histsig) 62 | 63 | 64 | def entropy(data): 65 | pk = sp.stats.rv_histogram(np.histogram(data, bins=20)).pdf(data) 66 | return sp.stats.entropy(pk) 67 | 68 | 69 | def kurtosis(data): 70 | return sp.stats.kurtosis(data) 71 | 72 | 73 | ##np.diff后一个元素减去前一个 np.sign函数返回的是一个由 1 和 -1 组成的数组 74 | def zero_cross(data): 75 | return len(np.where(np.diff(np.sign(data)))[0]) 76 | 77 | 78 | def min(data): 79 | return np.min(data) 80 | 81 | 82 | def max(data): 83 | return np.max(data) 84 | 85 | 86 | def var(data): 87 | return np.var(data) 88 | 89 | 90 | def mean(data): 91 | return np.mean(data) 92 | 93 | 94 | def median(data): 95 | return np.median(data) 96 | 97 | 98 | def wamp(signal, th=5e-3): 99 | x = abs(np.diff(signal)) 100 | umbral = x >= th 101 | return np.sum(umbral) 102 | 103 | 104 | def ssc(signal, threshold=1e-5): 105 | signal = np.array(signal) 106 | temp = [(signal[i] - signal[i - 1]) * (signal[i] - signal[i + 1]) for i in range(1, signal.shape[0] - 1, 1)] 107 | temp = np.array(temp) 108 | 109 | temp = temp[temp >= threshold] 110 | return temp.shape[0] 111 | 112 | 113 | def aac(signal): 114 | signal = np.array(signal) 115 | length = signal.shape[0] 116 | wl = [abs(signal[i + 1] - signal[i]) for i in range(length - 1)] 117 | return np.mean(wl) 118 | 119 | 120 | '''数据处理分割线''' 121 | 122 | 123 | def get_data(path, file): 124 | mat = loadmat(os.path.join(path, file)) 125 | data = pd.DataFrame(mat['emg']) 126 | df_len = np.min([len(mat['emg']), len(mat['stimulus'])]) 127 | data = pd.DataFrame(mat['emg'][:df_len]) 128 | data['stimulus'] = mat['stimulus'][:df_len] 129 | data['repetition'] = mat['repetition'][:df_len] 130 | return data 131 | 132 | 133 | def get_redata(path, file): 134 | mat = loadmat(os.path.join(path, file)) 135 | df_len = np.min([len(mat['emg']), len(mat['restimulus'])]) 136 | data = pd.DataFrame(mat['emg'][:df_len]) 137 | data['restimulus'] = mat['restimulus'][:df_len] 138 | data['rerepetition'] = mat['rerepetition'][:df_len] 139 | 140 | return data 141 | 142 | 143 | def normalise(data, train_reps, channel=12): 144 | x = [np.where(data.values[:, channel + 1] == rep) for rep in train_reps] 145 | indices = np.squeeze(np.concatenate(x, axis=-1)) 146 | train_data = data.iloc[indices, :] 147 | train_data = data.reset_index(drop=True) 148 | scaler = StandardScaler(with_mean=True, 149 | with_std=True, 150 | copy=False).fit(train_data.iloc[:, :channel]) 151 | 152 | scaled = scaler.transform(data.iloc[:, :channel]) 153 | normalised = pd.DataFrame(scaled) 154 | normalised['stimulus'] = data['stimulus'].values 155 | normalised['repetition'] = data['repetition'].values 156 | 157 | return normalised 158 | 159 | 160 | def filter_data(data, f, butterworth_order=4, btype='lowpass', channel=12): 161 | emg_data = data.values[:, :channel] 162 | 163 | f_sampling = 2000 164 | nyquist = f_sampling / 2 165 | if isinstance(f, int): 166 | fc = f / nyquist 167 | else: 168 | fc = list(f) 169 | for i in range(len(f)): 170 | fc[i] = fc[i] / nyquist 171 | 172 | b, a = signal.butter(butterworth_order, fc, btype=btype) 173 | transpose = emg_data.T.copy() 174 | 175 | for i in range(len(transpose)): 176 | transpose[i] = (signal.lfilter(b, a, transpose[i])) 177 | 178 | filtered = pd.DataFrame(transpose.T) 179 | filtered['stimulus'] = data['stimulus'].values 180 | filtered['repetition'] = data['repetition'].values 181 | 182 | return filtered 183 | 184 | 185 | def refilter_data(data, f, butterworth_order=4, btype='lowpass', channel=12): 186 | emg_data = data.values[:, :channel] 187 | 188 | f_sampling = 2000 189 | nyquist = f_sampling / 2 190 | if isinstance(f, int): 191 | fc = f / nyquist 192 | else: 193 | fc = list(f) 194 | for i in range(len(f)): 195 | fc[i] = fc[i] / nyquist 196 | 197 | b, a = signal.butter(butterworth_order, fc, btype=btype) 198 | transpose = emg_data.T.copy() 199 | 200 | for i in range(len(transpose)): 201 | transpose[i] = (signal.lfilter(b, a, transpose[i])) 202 | 203 | filtered = pd.DataFrame(transpose.T) 204 | filtered['restimulus'] = data['restimulus'].values 205 | filtered['rerepetition'] = data['rerepetition'].values 206 | 207 | return filtered 208 | 209 | 210 | def rectify(data): 211 | return abs(data) 212 | 213 | 214 | def windowing(data, reps, gestures, win_len, win_stride): 215 | if reps: 216 | x = [np.where(data.values[:, 13] == rep) for rep in reps] 217 | indices = np.squeeze(np.concatenate(x, axis=-1)) 218 | data = data.iloc[indices, :] 219 | data = data.reset_index(drop=True) 220 | 221 | if gestures: 222 | x = [np.where(data.values[:, 12] == move) for move in gestures] 223 | indices = np.squeeze(np.concatenate(x, axis=-1)) 224 | data = data.iloc[indices, :] 225 | data = data.reset_index(drop=True) 226 | 227 | # 没有reps和gestures标签时,保留所有数据 228 | idx = [i for i in range(win_len, len(data), win_stride)] 229 | 230 | X = np.zeros([len(idx), win_len, len(data.columns) - 2]) 231 | y = np.zeros([len(idx), ]) 232 | reps = np.zeros([len(idx), ]) 233 | 234 | for i, end in enumerate(tqdm(idx)): 235 | start = end - win_len 236 | X[i] = data.iloc[start:end, 0:12] 237 | y[i] = data.iloc[end, 12] 238 | reps[i] = data.iloc[end, 13] 239 | 240 | return X, y, reps 241 | 242 | 243 | def train_model(model, X_train_wind, y_train_wind, X_test_wind, y_test_wind, save_to, epoch=300): 244 | from tensorflow import keras as K 245 | opt_adam = K.optimizers.Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0) 246 | model.compile(loss='categorical_crossentropy', optimizer=opt_adam, metrics=['categorical_accuracy']) 247 | 248 | # log_dir="logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") 249 | 250 | es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=30) 251 | mc = ModelCheckpoint(save_to + '_best_model.h5', monitor='val_categorical_accuracy', mode='max', verbose=1, 252 | save_best_only=True) 253 | 254 | history = model.fit(x=X_train_wind, y=y_train_wind, epochs=epoch, shuffle=True, 255 | verbose=1, 256 | validation_data=(X_test_wind, y_test_wind), callbacks=[es, mc]) 257 | 258 | saved_model = load_model(save_to + '_best_model.h5') 259 | # evaluate the model 260 | _, train_acc = saved_model.evaluate(X_train_wind, y_train_wind, verbose=0) 261 | _, test_acc = saved_model.evaluate(X_test_wind, y_test_wind, verbose=0) 262 | print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) 263 | 264 | return history, saved_model 265 | 266 | 267 | def get_categorical(y): 268 | return pd.get_dummies(pd.Series(y)).values 269 | 270 | 271 | def plot_cnf_matrix(saved_model, X_valid_cv, target): 272 | y_pred = saved_model.predict(X_valid_cv) 273 | model_predictions = [list(y_pred[i]).index(y_pred[i].max()) + 1 for i in range(len(y_pred))] 274 | 275 | conf_mx = confusion_matrix(target, model_predictions) 276 | plt.matshow(conf_mx) 277 | plt.show() 278 | 279 | 280 | def feature_extractor(features, shape, data): 281 | l = pd.DataFrame() 282 | for i, function in enumerate(tqdm(features)): 283 | feature = [] 284 | print("Extracting feature....{}".format(str(function))) 285 | for i in range(data.shape[0]): 286 | for j in range(data.shape[2]): 287 | feature.append(function(data[i][:, j])) 288 | feature = np.reshape(feature, shape) 289 | l = pd.concat([l, pd.DataFrame(feature)], axis=1) 290 | print("Done extracting feature....{}".format(str(function))) 291 | 292 | return l 293 | 294 | 295 | '''频域特征(为减少spectrum重复计算,重写的特征提取方法)''' 296 | 297 | 298 | def frequency_features_extractor(shape, data, fs=2000): 299 | from Util.feature_set import spectrum, frequency_ratio, mean_freq, median_freq 300 | 301 | # for index, function in enumerate(features): 302 | # if function not in ["fr", "mnp", "tot", "mnf", "mdf", "pkf"]: 303 | # print(str(function)+"没有收录") 304 | 305 | fr = [] 306 | mnp = [] 307 | mnf = [] 308 | # mdf = [] 309 | # pkf = [] 310 | l = pd.DataFrame() 311 | 312 | for i in tqdm(list(range(data.shape[0]))): 313 | 314 | for j in range(data.shape[2]): 315 | frequency, power = spectrum(data[i][:, j], fs) 316 | fr.append(frequency_ratio(frequency, power)) # Frequency ratio 317 | mnp.append(np.sum(power) / len(power)) # Mean power 318 | # # tot.append(np.sum(power)) # Total power 319 | mnf.append(mean_freq(frequency, power)) # Mean frequency 320 | # mdf.append(median_freq(frequency, power)) # Median frequency 321 | # pkf.append(frequency[power.argmax()]) # Peak frequency 322 | 323 | fr = np.reshape(fr, shape) 324 | l = pd.concat([l, pd.DataFrame(fr)], axis=1) 325 | mnp = np.reshape(mnp, shape) 326 | l = pd.concat([l, pd.DataFrame(mnp)], axis=1) 327 | # # tot = np.reshape(tot, shape) 328 | # # l = pd.concat([l, pd.DataFrame(tot)], axis=1) 329 | mnf = np.reshape(mnf, shape) 330 | l = pd.concat([l, pd.DataFrame(mnf)], axis=1) 331 | # mdf = np.reshape(mdf, shape) 332 | # l = pd.concat([l, pd.DataFrame(mdf)], axis=1) 333 | # pkf = np.reshape(pkf, shape) 334 | # l = pd.concat([l, pd.DataFrame(pkf)], axis=1) 335 | 336 | return l 337 | 338 | 339 | def pca(data, comp): 340 | l = PCA(n_components=comp) 341 | l.fit(data) 342 | x_pca = l.transform(data) 343 | return pd.DataFrame(x_pca) 344 | 345 | 346 | def get_validation_curve(classifier, parameter, param_range, X, 347 | y): # A generalized function to plot validation curve for all 3 classifiers. 348 | train_scores, test_scores = validation_curve( 349 | classifier, X, y, param_name=parameter, param_range=param_range, 350 | scoring="accuracy", n_jobs=1) 351 | train_scores_mean = np.mean(train_scores, axis=1) 352 | train_scores_std = np.std(train_scores, axis=1) 353 | test_scores_mean = np.mean(test_scores, axis=1) 354 | test_scores_std = np.std(test_scores, axis=1) 355 | 356 | plt.title("Validation Curve with {}".format(classifier.__class__.__name__)) 357 | plt.xlabel(str(parameter)) 358 | plt.ylabel("Score") 359 | plt.ylim(0.0, 1.1) 360 | lw = 2 361 | plt.semilogx(param_range, train_scores_mean, label="Training score", 362 | color="darkorange", lw=lw) 363 | plt.fill_between(param_range, train_scores_mean - train_scores_std, 364 | train_scores_mean + train_scores_std, alpha=0.2, 365 | color="darkorange", lw=lw) 366 | plt.semilogx(param_range, test_scores_mean, label="Cross-validation score", 367 | color="navy", lw=lw) 368 | plt.fill_between(param_range, test_scores_mean - test_scores_std, 369 | test_scores_mean + test_scores_std, alpha=0.2, 370 | color="navy", lw=lw) 371 | plt.legend(loc="best") 372 | 373 | return plt 374 | 375 | 376 | def plot_learning_curve(estimator, title, X, y, axes=None, ylim=None, cv=None, 377 | n_jobs=None, train_sizes=np.linspace(.1, 1.0, 5)): 378 | """ 379 | Generate 3 plots: the test and training learning curve, the training 380 | samples vs fit times curve, the fit times vs score curve. 381 | 382 | Parameters 383 | ---------- 384 | estimator : estimator instance 385 | An estimator instance implementing `fit` and `predict` methods which 386 | will be cloned for each validation. 387 | 388 | title : str 389 | Title for the chart. 390 | 391 | X : array-like of shape (n_samples, n_features) 392 | Training vector, where ``n_samples`` is the number of samples and 393 | ``n_features`` is the number of features. 394 | 395 | y : array-like of shape (n_samples) or (n_samples, n_features) 396 | Target relative to ``X`` for classification or regression; 397 | None for unsupervised learning. 398 | 399 | axes : array-like of shape (3,), default=None 400 | Axes to use for plotting the curves. 401 | 402 | ylim : tuple of shape (2,), default=None 403 | Defines minimum and maximum y-values plotted, e.g. (ymin, ymax). 404 | 405 | cv : int, cross-validation generator or an iterable, default=None 406 | Determines the cross-validation splitting strategy. 407 | Possible inputs for cv are: 408 | 409 | - None, to use the default 5-fold cross-validation, 410 | - integer, to specify the number of folds. 411 | - :term:`CV splitter`, 412 | - An iterable yielding (train, test) splits as arrays of indices. 413 | 414 | For integer/None inputs, if ``y`` is binary or multiclass, 415 | :class:`StratifiedKFold` used. If the estimator is not a classifier 416 | or if ``y`` is neither binary nor multiclass, :class:`KFold` is used. 417 | 418 | Refer :ref:`User Guide ` for the various 419 | cross-validators that can be used here. 420 | 421 | n_jobs : int or None, default=None 422 | Number of jobs to run in parallel. 423 | ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context. 424 | ``-1`` means using all processors. See :term:`Glossary ` 425 | for more details. 426 | 427 | train_sizes : array-like of shape (n_ticks,) 428 | Relative or absolute numbers of training examples that will be used to 429 | generate the learning curve. If the ``dtype`` is float, it is regarded 430 | as a fraction of the maximum size of the training set (that is 431 | determined by the selected validation method), i.e. it has to be within 432 | (0, 1]. Otherwise it is interpreted as absolute sizes of the training 433 | sets. Note that for classification the number of samples usually have 434 | to be big enough to contain at least one sample from each class. 435 | (default: np.linspace(0.1, 1.0, 5)) 436 | """ 437 | if axes is None: 438 | _, axes = plt.subplots(1, 3, figsize=(20, 5)) 439 | 440 | axes[0].set_title(title) 441 | if ylim is not None: 442 | axes[0].set_ylim(*ylim) 443 | axes[0].set_xlabel("Training examples") 444 | axes[0].set_ylabel("Score") 445 | 446 | train_sizes, train_scores, test_scores, fit_times, _ = \ 447 | learning_curve(estimator, X, y, cv=cv, n_jobs=n_jobs, 448 | train_sizes=train_sizes, 449 | return_times=True) 450 | train_scores_mean = np.mean(train_scores, axis=1) 451 | train_scores_std = np.std(train_scores, axis=1) 452 | test_scores_mean = np.mean(test_scores, axis=1) 453 | test_scores_std = np.std(test_scores, axis=1) 454 | fit_times_mean = np.mean(fit_times, axis=1) 455 | fit_times_std = np.std(fit_times, axis=1) 456 | 457 | # Plot learning curve 458 | axes[0].grid() 459 | axes[0].fill_between(train_sizes, train_scores_mean - train_scores_std, 460 | train_scores_mean + train_scores_std, alpha=0.1, 461 | color="r") 462 | axes[0].fill_between(train_sizes, test_scores_mean - test_scores_std, 463 | test_scores_mean + test_scores_std, alpha=0.1, 464 | color="g") 465 | axes[0].plot(train_sizes, train_scores_mean, 'o-', color="r", 466 | label="Training score") 467 | axes[0].plot(train_sizes, test_scores_mean, 'o-', color="g", 468 | label="Cross-validation score") 469 | axes[0].legend(loc="best") 470 | 471 | # Plot n_samples vs fit_times 472 | axes[1].grid() 473 | axes[1].plot(train_sizes, fit_times_mean, 'o-') 474 | axes[1].fill_between(train_sizes, fit_times_mean - fit_times_std, 475 | fit_times_mean + fit_times_std, alpha=0.1) 476 | axes[1].set_xlabel("Training examples") 477 | axes[1].set_ylabel("fit_times") 478 | axes[1].set_title("Scalability of the model") 479 | 480 | # Plot fit_time vs score 481 | axes[2].grid() 482 | axes[2].plot(fit_times_mean, test_scores_mean, 'o-') 483 | axes[2].fill_between(fit_times_mean, test_scores_mean - test_scores_std, 484 | test_scores_mean + test_scores_std, alpha=0.1) 485 | axes[2].set_xlabel("fit_times") 486 | axes[2].set_ylabel("Score") 487 | axes[2].set_title("Performance of the model") 488 | 489 | return plt 490 | 491 | 492 | def notch_filter(data, f0, Q, fs=2000, channel=12): 493 | emg_data = data.values[:, :channel] 494 | b, a = signal.iirnotch(f0, Q, fs) 495 | transpose = emg_data.T.copy() 496 | 497 | for i in range(len(transpose)): 498 | transpose[i] = (signal.lfilter(b, a, transpose[i])) 499 | 500 | filtered = pd.DataFrame(transpose.T) 501 | filtered['stimulus'] = data['stimulus'].values 502 | filtered['repetition'] = data['repetition'].values 503 | return filtered 504 | 505 | 506 | def notch_refilter(data, f0, Q, fs=2000, channel=12): 507 | emg_data = data.values[:, :channel] 508 | b, a = signal.iirnotch(f0, Q, fs) 509 | transpose = emg_data.T.copy() 510 | 511 | for i in range(len(transpose)): 512 | transpose[i] = (signal.lfilter(b, a, transpose[i])) 513 | 514 | filtered = pd.DataFrame(transpose.T) 515 | filtered['restimulus'] = data['restimulus'].values 516 | filtered['rerepetition'] = data['rerepetition'].values 517 | return filtered --------------------------------------------------------------------------------