本示例说明如何使用长短期记忆LSTM网络对序列数据的每个时间步进行分类。
要训练深度神经网络对序列数据的每个时间步进行分类,可以使用序列到序列LSTM网络。序列到序列LSTM网络可以使得对序列数据的每个单独时间步进行不同的预测。
本示例使用了从佩戴在身上的智能手机获得的传感器数据,该示例训练了一个LSTM网络,在给定时间序列数据的情况下识别佩戴者的活动,该时间序列数据表示在三个不同方向上的加速度计的读数。训练数据包含其个人的时间序列数据。每个序列具有三个特征,并且长度不同,数据集包含6个训练观察结果和一个测试观察结果。
加载序列数据
加载人类活动识别数据。数据包含七个时间序列的传感器数据,这些数据是从穿戴在身上的智能手机获得的。每个序列有三个特征,并且特征不同。这三个功能分别对应三个方向上的加速度计数器。
load HumanActivityTrainXTrain
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});figurefor j = 1:numel(classes)label = classes(j);idx = find(YTrain{1} == label);hold onplot(idx,X(idx))endhold offxlabel("Time Step")ylabel("Acceleration")title("Training Sequence 1, Feature 1")legend(classes,'Location','northwest')
定义LSTM网络架构
定义一下LSTM网络架构,确定LSTM的输入的大小为3(因为这是输入数据的特征个数),确定LSTM的隐藏层个数为200,输出整个序列。最后,通过设定全连接层的个数为5能够分辨出5个类来,然后紧跟着一个softmax层和一个分类层。(大小为3的输入层->大小为200的隐藏层->大小为5的全阶层->softmax层->分类层)。
numFeatures = 3;numHiddenUnits = 200;numClasses = 5;layers = [...sequenceInputLayer(numFeatures)lstmLayer(numHiddenUnits, 'OutputMode', 'sequence')fullyConnectedLayer(numClasses)softmaxLayerclassificationLayer];
确定一下网络层的参数,设定解决方法为 ‘adam’,训练60个epochs。为了防止梯度爆炸,设定梯度阈值为2
options = trainingOptions('adam', ...'MaxEpochs',60, ...'GradientThreshold',2, ...'Verbose',0, ...'Plots','training-progress');
使用 trainNetwork函数来训练LSTM网络,每个小批量都包含整个训练集,所以每个epoch都会更新一次,因为序列很长,所以在处理每个批量和更新画图的时候都要花很长时间。
net = trainNetwork(XTrain, YTrain, layers, options);
测试LSTM网络
加载测试集然后对每个时间步长的活动进行分类。
加载人类活动的测试集,其中XTest包含了3维的序列,YTest包含了序列所对应的步长所属的标签。
load HumanActivityTestfigureplot(XTest{1}')xlabel("Time Step")legend("Feature " + (1:numFeatures))title("Test Data")

图3. 验证集
使用classify函数对测试集数据进行分类
YPred = classify(net, XTest{1});
另外,也可以使用函数classifyAndUpdateState然后来一次预测一个时间步长。通常,与一次一次的与预测相比,对全序列预测会更快。
计算预测的准确性
acc = sum(YPred == YTest{1})./numel(YTest{1})
acc = 0.9998
画图来看一下预测数据和真实数据的差别
figureplot(YPred,'.-')hold onplot(YTest{1})hold offxlabel("Time Step")ylabel("Activity")title("Predicted Activities")legend(["Predicted" "Test Data"])

图5. 预测数据和真实数据的差别


