MATLAB中LSTM时序分类实战详解

引用
1.MATLAB中外部数据读取并写入元胞数组的方法与步骤:
2.MATLAB中LSTM时序分类的用法与实战:

本文结合前面两篇文章综合运用于实战中,阅读此文章前建议先看该两篇文章

1.数据集

本次实战选自本人内部采集的脑电数据集,共四种类型,对应文件个数分别为10,7,7,5,分别命名为z1 ~ z10 , x1 ~ x7 , j1 ~ j7 , f1 ~ f5,文件中时间序列的特征维数是4,文件以.scv格式保存(以逗号为分隔符)。样式如下 :

LSTM matlab 2020a 机器学习_matlab


由于数据集较少,取训练集的个数分别为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)

训练结果

LSTM matlab 2020a 机器学习_时间序列_02


检测结果

YPred = 
  4×1 categorical 数组
     2 
     2 
     3 
     2 
     
acc =

    0.5000