MATLAB中LSTM时序分类实战详解
引用
1.MATLAB中外部数据读取并写入元胞数组的方法与步骤:
2.MATLAB中LSTM时序分类的用法与实战:
本文结合前面两篇文章综合运用于实战中,阅读此文章前建议先看该两篇文章
1.数据集
本次实战选自本人内部采集的脑电数据集,共四种类型,对应文件个数分别为10,7,7,5,分别命名为z1 ~ z10 , x1 ~ x7 , j1 ~ j7 , f1 ~ f5,文件中时间序列的特征维数是4,文件以.scv格式保存(以逗号为分隔符)。样式如下 :

由于数据集较少,取训练集的个数分别为9,6,6,4,预测集的个数为1,1,1,1。
2.代码
%% 输入XTrain
filepath='F:\脑电\记录\数据处理1\类型1\'; %为了循环输入文件,先把文件前面的相同路径写出
for i=1:9 %循环读取
fileID=fopen([filepath,'z',num2str(i),'.csv']); %矩阵形式组合成路径字符串
a_txt=textscan(fileID,'%s',4,'Delimiter',','); %为了读取数据,先读文本
%其中4表示读取4次(注意该格式是读一个不是一列),结束后光标移到数字之前
XTrain(i)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
%读取数据,四列都将储存在一个元胞单元中(单引号和逗号较多,注意区分)
fclose(fileID);
end
filepath='F:\脑电\记录\数据处理1\类型2\';
for i=10:15
fileID=fopen([filepath,'x',num2str(i-9),'.csv']);
a_txt=textscan(fileID,'%s',4,'Delimiter',',');
XTrain(i)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
fclose(fileID);
end
filepath='F:\脑电\记录\数据处理1\类型3\';
for i=16:22
fileID=fopen([filepath,'j',num2str(i-15),'.csv']);
a_txt=textscan(fileID,'%s',4,'Delimiter',',');
XTrain(i)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
fclose(fileID);
end
filepath='F:\脑电\记录\数据处理1\类型4\';
for i=23:26
fileID=fopen([filepath,'f',num2str(i-22),'.csv']);
a_txt=textscan(fileID,'%s',4,'Delimiter',',');
XTrain(i)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
fclose(fileID);
end
%注意到元胞单元size必须为4-by-N而不是N-by-4
%(其中4是维度,必须是维度为行数,要不然会报错),将每一个元胞单元转置
XTrain=XTrain';
[n,m]=size(XTrain);
for i=1:n
XTrain{i}=XTrain{i}.';%注意这里用的是花括号不是圆括号,自己尝试下就知道区别了
end
%% 输入YTrain
for i=1:9
YTrain(i)=1;
end
for i=10:15
YTrain(i)=2;
end
for i=16:22
YTrain(i)=3;
end
for i=23:26
YTrain(i)=4;
end
YTrain=categorical(YTrain');%将数值数组转化为类别数组
%% 输入XTest
fileID=fopen('F:\脑电\记录\数据处理1\类型1\z10.csv');
a_txt=textscan(fileID,'%s',4,'Delimiter',',');
XTest(1)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
fclose(fileID);
fileID=fopen('F:\脑电\记录\数据处理1\类型2\x7.csv');
a_txt=textscan(fileID,'%s',4,'Delimiter',',');
XTest(2)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
fclose(fileID);
fileID=fopen('F:\脑电\记录\数据处理1\类型3\j7.csv');
a_txt=textscan(fileID,'%s',4,'Delimiter',',');
XTest(3)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
fclose(fileID);
fileID=fopen('F:\脑电\记录\数据处理1\类型4\f5.csv');
a_txt=textscan(fileID,'%s',4,'Delimiter',',');
XTest(4)=textscan(fileID,repmat('%d',[1,4]),'Delimiter',',','CollectOutput',1);
fclose(fileID);
XTest=XTest';
[n,m]=size(XTest);
for i=1:n
XTest{i}=XTest{i}.';
end
%% 输入YTest
YTest=categorical([1 2 3 4]');
%% 构建LSTM网络
inputSize = 4;%特征维数
numHiddenUnits = 100;%LSTM网路包含的隐藏单元数目
numClasses = 4;%分类数
layers = [ ...
sequenceInputLayer(inputSize)
lstmLayer(numHiddenUnits,'OutputMode','last')
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer];
maxEpochs = 400;%最大训练周期数
miniBatchSize = 27;%分块尺寸
options = trainingOptions('adam', ...
'ExecutionEnvironment','cpu', ...
'MaxEpochs',maxEpochs, ...
'MiniBatchSize',miniBatchSize, ...
'GradientThreshold',1, ...
'Verbose',false, ...
'Plots','training-progress');
%% 训练
net=trainNetwork(XTrain,YTrain,layers, options)
%% 预测
miniBatchSize = 27;
YPred = classify(net,XTest, ...
'MiniBatchSize',miniBatchSize, ...
'SequenceLength','longest')
%% 结果检验
acc = sum(YPred == YTest)./numel(YTest)训练结果

检测结果
YPred =
4×1 categorical 数组
2
2
3
2
acc =
0.5000
















