MATLAB LSTM多输入多输出 模式分类 示例解析(含代码)

目录

项目背景

加载序列数据

定义 LSTM 网络架构

训练LSTM网络

测试 LSTM 网络

使用 classify 对测试数据进行分类。

计算预测的准确度。

全部源代码

参考文献


项目背景

  • 此示例使用从佩戴在身体上的智能手机获得的传感器数据。该示例训练一个 LSTM 网络,旨在根据表示三个不同方向上的加速度计读数的时间序列数据来识别佩戴者的活动。训练数据包含七个人的时间序列数据。每个序列有三个特征,且长度不同。该数据集包含六个训练观测值和一个测试观测值。
  • 本文初衷在于帮助初学者创建LSTM网络,网络上很多介绍停留理论层面,反复地说LSTM网络的特点而忽略matlab创建的实际过程,或者以收费的形式贩卖mathwork里的实例,对学生党不友好。
  • LSTM网络简介:LSTM 网络常用于对序列数据进行分类 。LSTM 网络是一种循环神经网络 (RNN),可学习序列数据的时间步之间的长期依存关系。
  • 输入输出模式:LSTM网络按输入输出模式可分sequence to sequence网络与sequence to last(label)网络,前者多输入多输出,后者多输入单输出,本实例为sequence to sequence输入输出模式,例子来源mathwork。
  • 输入输出详细情况:该实例输入类型为cell型1*Y矩阵,每个元胞内为3*X的矩阵,3个特征*X个时间步(每个元胞内X可以不同)。输出类型为1*Ycell类型,每个cell内矩阵大小为1*X,其中是对对应输入元胞每个X标注的类别。(sequence to sequence。

重点:对于LSTM网络的两种工作模式,

  • 1、输入 特征数*时间步 矩阵,输出对每个时间步的模式分类(sequence to sequence)。  2、输入 特征数*时间步 矩阵,输出对整体(最后一个时间步)的模式分类(sequence to last)。
  • 这两种工作模式输入相同输出不同,前者输出为1*Ycell类型矩阵,每个cell内矩阵大小为:1*X(它对每一个时间步作分类)。后者输出为categorical类型分类列向量,大小为Y*1(它对输入中每个元胞包含序列的整体作分类)
  • 要训练深度神经网络以对序列数据的每个时间步进行分类,可以使用“序列到序列”LSTM 网络。通过“序列到序列”LSTM 网络,您可以对序列数据的每个时间步进行不同预测。

加载序列数据

加载人体活动识别数据。该数据包含从佩戴在身体上的智能手机获得的七个时间序列的传感器数据。每个序列有三个特征,且长度不同。这三个特征对应于三个不同方向上的加速度计读数。该例子来源mathwork,直接输入下列代码即可得到数据

load HumanActivityTrain

XTrain
XTrain=6×1 cell array
    {3×64480 double}
    {3×53696 double}
    {3×56416 double}
    {3×50688 double}
    {3×51888 double}
    {3×54256 double}

在绘图中可视化一个训练序列。绘制第一个训练序列的第一个特征,并按照对应的活动为绘图着色。

X = XTrain{1}(1,:);
classes = categories(YTrain{1});

figure
for j = 1:numel(classes)
    label = classes(j);
    idx = find(YTrain{1} == label);
    hold on
    plot(idx,X(idx))
end
hold off

xlabel("Time Step")
ylabel("Acceleration")
title("Training Sequence 1, Feature 1")
legend(classes,'Location','northwest')

MATLAB LSTM多输入多输出 模式分类 示例解析(含代码)_第1张图片

定义 LSTM 网络架构

定义 LSTM 网络架构。将输入指定为大小为 3(输入数据的特征数量)的序列。指定包含 200 个隐含单元的 LSTM 层,并输出完整序列。最后,在网络中包含一个大小为 5 的全连接层,后跟 softmax 层和分类层,以此来指定五个类。

numFeatures = 3;
numHiddenUnits = 200;
numClasses = 5;

layers = [ ...
    sequenceInputLayer(numFeatures)
    lstmLayer(numHiddenUnits,'OutputMode','sequence')
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer];
%指定训练选项。将求解器设置为 'adam'。进行 60 轮训练。要防止梯度爆炸,请将梯度阈值设置为 2。

options = trainingOptions('adam', ...
    'MaxEpochs',60, ...
    'GradientThreshold',2, ...
    'Verbose',0, ...
    'Plots','training-progress');
%使用 trainNetwork 以指定的训练选项训练 LSTM 网络。每个小批量都包含整个训练集,因此每训练一轮便更新一次绘图。序列非常长,因此处理每个小批量并更新绘图可能需要一些时间。

训练LSTM网络

net = trainNetwork(XTrain,YTrain,layers,options);

MATLAB LSTM多输入多输出 模式分类 示例解析(含代码)_第2张图片

测试 LSTM 网络

加载测试数据并对每个时间步的活动进行分类。

加载人体活动测试数据。XTest 包含一个维度为 3 的序列。YTest 包含对应于每个时间步的活动的分类标签序列。

load HumanActivityTest
figure
plot(XTest{1}')
xlabel("Time Step")
legend("Feature " + (1:numFeatures))
title("Test Data")

MATLAB LSTM多输入多输出 模式分类 示例解析(含代码)_第3张图片

使用 classify 对测试数据进行分类。

YPred = classify(net,XTest{1});

您也可以使用 classifyAndUpdateState 一次对一个时间步进行预测。这在时间步的值以流的方式到达时非常有用。通常,对完整序列进行预测比一次对一个时间步进行预测更快。

计算预测的准确度。

acc = sum(YPred == YTest{1})./numel(YTest{1})

acc = 0.9998

%通过绘图将预测值与测试数据进行比较。

figure
plot(YPred,'.-')
hold on
plot(YTest{1})
hold off

xlabel("Time Step")
ylabel("Activity")
title("Predicted Activities")
legend(["Predicted" "Test Data"])

MATLAB LSTM多输入多输出 模式分类 示例解析(含代码)_第4张图片

全部源代码

load HumanActivityTrain

X = XTrain{1}(1,:);
classes = categories(YTrain{1});

figure
for j = 1:numel(classes)
    label = classes(j);
    idx = find(YTrain{1} == label);
    hold on
    plot(idx,X(idx))
end
hold off

xlabel("Time Step")
ylabel("Acceleration")
title("Training Sequence 1, Feature 1")
legend(classes,'Location','northwest')

numFeatures = 3;
numHiddenUnits = 200;
numClasses = 5;

layers = [ ...
    sequenceInputLayer(numFeatures)
    lstmLayer(numHiddenUnits,'OutputMode','sequence')
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer];
%指定训练选项。将求解器设置为 'adam'。进行 60 轮训练。要防止梯度爆炸,请将梯度阈值设置为 2。

options = trainingOptions('adam', ...
    'MaxEpochs',60, ...
    'GradientThreshold',2, ...
    'Verbose',0, ...
    'Plots','training-progress');
%使用 trainNetwork 以指定的训练选项训练 LSTM 网络。每个小批量都包含整个训练集,因此每训练一轮便更新一次绘图。序列非常长,因此处理每个小批量并更新绘图可能需要一些时间。

net = trainNetwork(XTrain,YTrain,layers,options);

load HumanActivityTest
figure
plot(XTest{1}')
xlabel("Time Step")
legend("Feature " + (1:numFeatures))
title("Test Data")

YPred = classify(net,XTest{1});

acc = sum(YPred == YTest{1})./numel(YTest{1})

%通过绘图将预测值与测试数据进行比较。

figure
plot(YPred,'.-')
hold on
plot(YTest{1})
hold off

xlabel("Time Step")
ylabel("Activity")
title("Predicted Activities")
legend(["Predicted" "Test Data"])

参考文献

[1]Mathwork:Sequence-to-Sequence Classification Using Deep Learning

你可能感兴趣的:(LSTM长短期记忆神经网络,matlab,lstm)