主要内容

手势分类使用雷达信号和深度学习

这个例子展示了如何分类超宽带(UWB)脉冲雷达信号数据使用一个多对于卷积神经网络(CNN)。

介绍

迁移型信号数据获得使用传感器,如超宽频脉冲雷达,包含模式针对不同的手势。关联运动数据与运动的好处有几种途径的工作。例如,对非接触式人机交互手势识别是重要的。这个例子旨在利用深度学习解决自动化特征提取从一个手势数据集内模式和提供一个标签为每个信号样本。

UWB-gestures是一个公开的数据集的动态手势(1]。它包含一个共有9600个样本来自8个不同的志愿者。获得每个记录,主考官放在一个单独的超宽频脉冲雷达在左边,上面,两边的实验装置,导致3接收雷达信号数据矩阵。志愿者进行手势的动作词汇组成的12个动态手的动作:

  1. 左右滑动(唐森刷卡)

  2. 左边/右边滑动(rl刷卡)

  3. 上下滑动(U-D刷卡)

  4. Down-up刷卡(du刷卡)

  5. Diagonal-left-right-up-down刷卡(Diag-LR-UD刷卡)

  6. Diagonal-left-right-down-up刷卡(Diag-LR-DU刷卡)

  7. Diagonal-right-left-up-down刷卡(Diag-RL-UD刷卡)

  8. Diagonal-right-left-down-up刷卡(Diag-RL-DU刷卡)

  9. 顺时针旋转

  10. 逆时针方向旋转

  11. 向内推

  12. 空的手势

因为每个手势运动是由三个独立的超宽频脉冲雷达捕获,我们将使用一个CNN架构,接受3作为单独的输入信号。CNN模型将从每个信号中提取特征信息结合到作最后一个动作时标签之前的预测。因此,对于一个多变量CNN将使用最小预处理的雷达信号数据矩阵进行分类不同的手势。

下载数据

每个雷达信号数据矩阵标记生成的手势。8种不同的人类志愿者执行12个单独的手势,总共96次试验在96年mat文件存储。每个MAT-file包含3雷达数据矩阵,对应3雷达实验中使用的设置。他们命名,,正确的。文件可以在以下位置:

https://ssd.mathworks.com/万博1manbetxsupportfiles/SPT/data/uwb-gestures.zip

下载数据文件到你的MATLAB示例目录。

datasetZipFolder = matlab.internal.examples.download万博1manbetxSupportFile (“SPT”,“数据/ uwb-gestures.zip”);datasetFolder =擦掉(datasetZipFolder,“zip”);如果~存在(datasetFolder“dir”)downloadLocation = fileparts (datasetZipFolder);解压缩(datasetZipFolder downloadLocation);结束

你也可以选择下载一个单独的文件,其中包括pre-trained网络,misoNet,存储在一个MAT-file命名pretrainedNetwork.mat。它可以在以下位置:

https://ssd.mathworks.com/万博1manbetxsupportfiles/SPT/data/uwb-gestures-network.zip

您可以跳过的训练步骤和使用pre-trained网络分类的设置doTraining。如果doTraining被设置为,pre-trained网络将下载后在这个例子。如果你想训练网络运行为例,确定设置doTraining真正的

doTraining = true;

探索数据

创建一个信号数据存储访问文件中的数据。指定信号变量名称要读取每个文件使用SignalVariableNames参数。本例假设数据集被储存在你的MATLAB示例目录下uwb-gestures文件夹中。如果不是这种情况,改变数据的路径datasetFolder变量。

sds = signalDatastore (datasetFolder,“IncludeSubfolders”,真的,“SignalVariableNames”,(“左”,“顶级”,“正确”),“FileExtensions”,“.mat”,“ReadOutputOrientation”,“行”);

数据存储返回三元素单元阵列的雷达信号矩阵包含左,,和正确的雷达,秩序。

预览(sds)
ans =1×3单元阵列{9000×189双}{9000×189双}{9000×189双}

每个雷达信号矩阵的行和列表示动作的持续时间(标准时间),手从雷达的距离(夏令时间),分别。在数据采集中,考官记录重复主题特定的手势为450秒,对应于9000年(标准时间)行。有1完整手势运动90年标准时间帧。这样,每个雷达信号矩阵包含了100个完整的手势动作样本。每个超宽频雷达的距离是1.2米,对应189夏令时间垃圾箱。

slowTimeFrames = 90;recordedTimePerSample = 4.5;radarRange = 1.2;

想象一个手势动作,指定一个超宽频雷达位置、姿态,手势样品(1 - 100)。

radarToPlot =1;gestureToPlot =“_G1_”;gestureSample =50;

获得的雷达信号矩阵选择手势和雷达的位置。

sdssubset =子集(sds,包含(sds.Files gestureToPlot));radarDataMatrix =阅读(sdssubset);radarDataMatrix = radarDataMatrix {radarToPlot};

使用正常化将手势信号数据范围在0和1之间,和使用显示亮度图像手势动作形象化样本。

normalizedRadarData =正常化(radarDataMatrix 2“范围”[0,1]);显示亮度图像([0 radarRange],[0 recordedTimePerSample],normalizedRadarData (slowTimeFrames * (gestureSample-1) + 1: slowTimeFrames * gestureSample:),[0 1]);集(gca),“YDir”,“正常”)标题(“原始信号”)包含(“距离雷达(m)”的手)ylabel (“动作时间(s)”)

正如你所看到的,很难辨别运动模式。

原始信号包含环境反射从身体部位或其他静态对象呈现在雷达的范围内。这些不必要的反射被称为“杂乱”,可以删除使用脉冲消除器执行一个指数移动平均线。这个操作的传递函数

H ( z ) = 1 - - - - - - z - - - - - - 1 1 - - - - - - α z - - - - - - 1

这样 α 是一个值 0 α 1 控制的平均量(2]。使用过滤器分子和分母系数系数设置为[1]和[1 -0.9),分别将杂物从原始信号。

clutterRemovedSignal =过滤器(-0.9 [1],[1]radarDataMatrix, [], 1);

可视化clutter-removed信号的差别。

normalizedClutterRemovedSignal =正常化(clutterRemovedSignal 2“范围”[0,1]);显示亮度图像([0 radarRange],[0 recordedTimePerSample],normalizedClutterRemovedSignal (slowTimeFrames * (gestureSample-1) + 1: slowTimeFrames * gestureSample:),[0 1]);集(gca),“YDir”,“正常”)标题(“Clutter-Removed信号”)包含(“距离雷达(m)”的手)ylabel (“动作时间(s)”)

注意,运动模式更明显了。例如,如果您选择想象左右滑动从左边的雷达的角度,你会发现从雷达的距离对手势的持续时间增加。

准备培训资料

MAT-file名称包含手势规范(G1, G2,…,G12) corresponding to labels for each radar signal matrix. Convert these codes to labels within the gesture vocabulary, using a categorical array.

(~,文件名)= fileparts (sds.Files);gestureLabels =提取(文件名,“G”+ digitsPattern);gestureCodes = [“G1”,“两国集团”,“G3”,“四国集团”,“G5”,“G6”,“七国集团”,“八国集团”,“国”,“十国集团”,“为G11”,“G12”];gestureVocabulary = [“唐森刷卡”,“rl刷卡”,“U-D刷卡”,“是du刷卡”,“Diag-LR-UD刷卡”,“Diag-LR-DU刷卡”,“Diag-RL-UD刷卡”,“Diag-RL-DU刷卡”,“顺时针”,“逆时针”,向内推,“空”];gestureLabels =分类(gestureLabels gestureCodes gestureVocabulary);

收集标签数组中数据存储。

labelDs = arrayDatastore (gestureLabels,“OutputType”,“细胞”);

结合信号数据存储和数组数据存储,为了获得一个包含从每个雷达信号数据的数据存储和分类标签。洗牌结果数据存储随机的顺序存储mat文件。

allDataDs =结合(sds、labelDs);allDataDs = shuffle (allDataDs);预览(allDataDs)
ans =1×4单元阵列{9000×189双}{9000×189双}{9000×189双}{[Diag-LR-UD刷卡]}

变换函数允许helper函数,processData数据应用,因为它是由数据存储中读取。processData执行上述描述的规范化和过滤部分标准化数据,清除杂物。此外,它将雷达信号矩阵划分为单独的手势动作样本。

allDataDs =变换(allDataDs @processData);预览(allDataDs)
ans =8×4单元阵列{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}{90×189双}{90×189双}{90×189双}{[Diag-LR-UD刷卡]}

神经网络训练是迭代。在每次迭代中,数据存储从文件中读取数据,并将数据在更新网络系数。由于数据正在读取单个样本,数据需要读入内存,之前re-shuffled并插入到另一个数据存储进行训练。

因为整个训练数据集适合在内存中,可以并行转换数据,如果并行计算工具可用,然后收集到工作区中。使用readallUseParallel标志设置为true,利用并行读取所有的信号数据池和标签到工作区中。如果数据适用于您的计算机的内存,将数据导入到工作区允许更快的训练因为数据读取和改变了只有一次。注意,如果数据不符合在内存中,您必须将数据存储到训练函数,和执行的转换是在每一个培训时代。

allData = readall (allDataDs,“UseParallel”,真正的);
开始平行池(parpool)使用“本地”概要文件…连接到平行池(工人数量:8)。

标签的最后一列返回allData。使用countlabels在数据集获取标签的比例值。注意手势是平衡的,并且在整个数据集。

countlabels (allData (: 4)
ans =12×3表标签数百分比___________ _____,______是du刷卡793 8.2664 Diag-LR-DU刷卡800 8.3394 Diag-LR-UD刷卡800 8.3394 Diag-RL-DU刷卡800 8.3394 Diag-RL-UD刷卡800 8.3394唐森刷卡800 8.3394 rl刷卡800 8.3394逆时针顺时针U-D刷卡800 8.3394 800 8.3394 800 8.3394空向内推800 8.3394 800 8.3394

把数据随机分成训练集和验证集,同时确保测试数据后离开。在这个例子中,训练、验证和测试将会70%,15%,和15%,分别。使用splitlabels将数据分为训练、验证和测试集与原始数据集比例保持同样的标签。指定随机选择洗牌在三组随机的数据。

idx = splitlabels (allData (:, 4), [0.7 - 0.15],“随机”);trainIdx = idx {1};valIdx = idx {2};testIdx = idx {3};

避免选择样本相同的随机化试验的指标。内存中的训练和验证数据存储在数组中数据存储,以便他们可以用来训练一个多输入网络。

trainData = allData (trainIdx (randperm(长度(trainIdx))),:);valData = allData (valIdx (randperm(长度(valIdx))),:);trainDataDs = arrayDatastore (trainData,“OutputType”,“相同”);valDataDs = arrayDatastore (valData,“OutputType”,“相同”);

准备培训网络

培训之前定义网络体系结构。因为每个手势运动是由三个独立的超宽频脉冲雷达捕获,我们将使用一个CNN架构接受3作为单独的输入信号。对于培训后的成果提出多输入多,CNN要比达到与另一个输入,对于CNN的输入是90 x 189 x 3堆雷达数据矩阵。

repeatBranch包含将执行的操作,分别在三个雷达数据信号矩阵。CNN模型需要将提取的特征信息从每个信号作最后一个动作时标签的预测。mainBranch包含操作将连接3repeatBranch输出和估计标签。指定一个imageInputLayer大小为90 x 189接受手势运动样本。指定一个additionLayer与数量的输入设置为3,收集3分支的输出,通过模型的分类部分。指定一个fullyConnectedLayer的输出尺寸12,一个用于每一个手势。添加一个softmaxLayer和一个classificationLayer输出估计标签。

repeatBranch = [imageInputLayer (90 189),“归一化”,“没有”)convolution2dLayer (3 8“填充”1)batchNormalizationLayer reluLayer maxPooling2dLayer (2“步”2)convolution2dLayer(16日“填充”1)batchNormalizationLayer reluLayer maxPooling2dLayer (2“步”32岁的,2)convolution2dLayer (3“填充”1)batchNormalizationLayer reluLayer maxPooling2dLayer (2“步”,2)convolution2dLayer (64,“填充”1)batchNormalizationLayer reluLayer maxPooling2dLayer (2“步”,2)];mainBranch = [additionLayer (3) fullyConnectedLayer (12) softmaxLayer classificationLayer);

定义一个layerGraphrepeatBranch添加3倍吗mainBranch添加一次。最终的输出连接maxPooling2dLayer在每一个repeatBranch的输入additionLayer

misoCNN = layerGraph ();misoCNN = addLayers (misoCNN repeatBranch);misoCNN = addLayers (misoCNN repeatBranch);misoCNN = addLayers (misoCNN repeatBranch);misoCNN = addLayers (misoCNN mainBranch);misoCNN = connectLayers (misoCNN,“maxpool_4”,“添加/三机一体”);misoCNN = connectLayers (misoCNN,“maxpool_8”,“添加/ in2”);misoCNN = connectLayers (misoCNN,“maxpool_12”,“添加/ in3”);

对于可视化多CNN。

情节(misoCNN);

选择选项训练过程,确保良好的网络性能。确保指定valDataDs作为ValidationData,所以它是用来验证在训练。指的是trainingOptions(深度学习工具箱)文档每个参数的描述。

选择= trainingOptions (“亚当”,“InitialLearnRate”1 e - 3,“MaxEpochs”3,“MiniBatchSize”32岁的“ValidationData”valDataDs,“ValidationFrequency”现年40岁的“详细”假的,“阴谋”,“训练进步”);

列车网络的

使用trainNetwork命令训练CNN。

如果doTraining = = true misoNet = trainNetwork (trainDataDs、misoCNN选项);其他的pretrainedNetworkZipFolder = matlab.internal.examples.download万博1manbetxSupportFile (“SPT”,“数据/ uwb-gestures-network.zip”);pretrainedNetworkFolder =擦掉(pretrainedNetworkZipFolder,“zip”);如果~存在(pretrainedNetworkFolder“dir”)downloadLocation = fileparts (pretrainedNetworkZipFolder);解压缩(pretrainedNetworkZipFolder downloadLocation);结束负载(fullfile (pretrainedNetworkFolder“pretrainedNetwork.mat”),“misoNet”);结束

分类测试数据

分类使用训练有素的CNN和测试数据分类命令。

testData = allData (testIdx:);testData ={猫(4,testData{: 1}),猫(4,testData{: 2}),猫(4,testData{: 3}),猫(1,testData {: 4})};actualLabels = testData {4};predictedLabels =分类(misoNet testData {1}, testData {2}, testData {3});精度=意味着(predictedLabels = = actualLabels);流(“精度测试集% 0.2 f % %”,100 *准确性)
精度的测试集是96.04%

可视化使用混淆矩阵的分类性能。

confusionchart (predictedLabels actualLabels);

最大的困惑是之间逆时针方向顺时针方向运动和向内推运动。

探索网络预测

您可以获得最后的分数max-pooling层每个输入部门更好地了解数据的每个雷达最终导致网络的信心。辅助功能,getActivationData返回softmax-normalized分数(概率为类成员)和指数对应3最高分数。

gestureToPlot =“唐森刷卡”;gestureToPlotIndices =找到(匹配(字符串(actualLabels), gestureToPlot));gestureSelection = randsample (gestureToPlotIndices, 1);actualLabel = actualLabels (gestureSelection);predictedLabel = predictedLabels (gestureSelection);allLabels =类别(actualLabels);[leftScores, leftClassIds] = getActivationData (misoNet、testData gestureSelection,“maxpool_4”);[topScores, topClassIds] = getActivationData (misoNet、testData gestureSelection,“maxpool_8”);[rightScores, rightClassIds] = getActivationData (misoNet、testData gestureSelection,“maxpool_12”);

使用辅助函数plotActivationData从每个雷达和可视化数据叠加3最高分数对应的标签在每个输入分支操作后完成。

t = tiledlayout (1、3);plotActivationData (testData allLabels、leftScores leftClassIds,gestureSelection [0 radarRange], [0 recordedTimePerSample],“左”);plotActivationData (testData allLabels、topScores topClassIds,gestureSelection [0 radarRange], [0 recordedTimePerSample],“顶级”);plotActivationData (testData allLabels、rightScores rightClassIds,gestureSelection [0 radarRange], [0 recordedTimePerSample],“正确”);标题(t) [“实际标签:“+字符串(actualLabel);“预测标签:“+字符串(predictedLabel)),“字形大小”12);包含(t)“距离雷达(m)”的手,“字形大小”11)ylabel (t,“动作时间(s)”,“字形大小”11)

结论

在这个示例中,您了解了如何使用多输入多CNN从3个独立的雷达数据提取信息矩阵和手势动作进行分类。应用体系结构允许我们利用来自多个传感器的数据记录相同的事件。

辅助函数

函数dataOut = processData (dataIn)标签= dataIn(结束);dataIn(结束)= [];dataOut = cellfun (@ (x)过滤器(-0.9 [1],[1],[],1),dataIn,“UniformOutput”、假);dataOut = cellfun (@ (x)正常化(x 2“范围”[0,1])、dataOut“UniformOutput”、假);dataOut =猫(1,dataOut {:});dataOut = mat2cell (dataOut, 90 *(1、大小(dataOut 1) / 90));dataOut =重塑(dataOut [], 3);dataOut(:, 4) =标签;结束函数[分数,classIds] = getActivationData(网络,testData、索引层)激活=激活(净,testData{1}(:,:,索引),testData{2}(:,:,索引),testData{3}(:,:,索引),层,“OutputAs”,“列”);fcWeights = net.Layers (end-2) .Weights;fcBias = net.Layers (end-2) .Bias;成绩= fcWeights *激活+ fcBias;成绩= exp(分数)/笔(exp(分数));[~,classIds] = maxk(分数,3);结束函数plotActivationData (testData、标签、分数、ids、sampleIdx xlimits, ylimits, plotTitle)如果plotTitle = =“左”手势= 1;elseifplotTitle = =“顶级”手势= 2;elseifplotTitle = =“正确”手势= 3;结束nexttile;显示亮度图像(xlimits、ylimits testData{姿态}(:,:,sampleIdx)[0 1])文本(plotTitle 0.3, 4日,“颜色”,“红色”,“FontWeight”,“大胆”,“HorizontalAlignment”,“中心”甘氨胆酸)组(,“YDir”,“正常”)标题(字符串(标签(ids)) +”:“+字符串(圆(分数(ids), 3)),“字形大小”8);结束

引用

[1]Ahmed年代。王,D。,Park, J. et al. UWB-gestures, a public dataset of dynamic hand gestures acquired using impulse radar sensors. Sci Data 8, 102 (2021). https://doi.org/10.1038/s41597-021-00876-0.

[2]拉萨罗,Girbau D, Villarino r .杂波抑制技术的肢体动作通过超宽频雷达在检测的呼吸活动。传感器(瑞士巴塞尔)。2014年2月,14 (2):2595 - 2618。DOI: 10.3390 / s140202595。

另请参阅

|(信号处理工具箱)|(信号处理工具箱)|