建立一个高5计数器使用深度学习
这篇文章来自布莱恩•道格拉斯,YouTube内容创造者控制系统和深度学习应用
十年,我想实现这个愚蠢的想法,我衡量一个人的手的加速度计算的次数一天中他们高5。我不确定如何使用基于规则的方法来实现这个算法开发,我熟悉所以坐在持有的项目。只有当我在做深度学习MATLAB技术演讲视频系列深,我才意识到学习是完美的解决这个问题!
第四届的主题系列的视频传输学习结果对我来说是关键的概念,我需要快速得到一个高5计数算法启动并运行。在这篇文章中,我将走过的细节我写的代码和工具我用来获得高5柜台工作的视频。希望你可以使用这个作为起点来解决这些困难的分类问题,你已经坐在了过去十年。
这篇文章分为以下部分:
所以,让我们去做吧!
硬件的概述
硬件设置非常简单。我有一个连接到一个加速度计Arduino Uno通过I2C总线。Arduino然后通过USB连接到我的电脑。
感应加速度,我使用微控制器- 9250。这是一个9自由度从TDK InvenSense惯性测量单元。而不是将芯片集成到自己的定制电路设计,我使用突破董事会暴露了权力、地面和I2C通信别针。我用这个芯片的唯一原因是因为我已经有了一个撒谎,但任何加速度计工作只要是足够小的快速移动。
你可以看到,我的硬件设置很粗暴地由一个案板和一些跳线但我认为这是一种不错的,你也不需要设置任何花哨的工作。
阅读MATLAB的加速度计
从微控制器读取加速度- 9250通过Arduino,我使用MATLAB为金宝appArduino硬件支持包。这个包可以让你与一个Arduino无需编译代码。另外,有一个内置的mpu9250函数允许您读取传感器使用一行命令。
只需要三行代码连接到Arduino,实例化一个MPU9250对象,并阅读加速度计。
数据预处理和量图
如果你看了4日视频系列技术讨论,深度学习,你就会知道,我选择使用硬件加速数据转换成一个图像利用GoogLeNet——网络训练识别图像。特别是,我使用一个连续小波变换创建一个量图。
量图是一种适用于信号的时频表示存在多尺度。,信号频率和慢变低,但与高频瞬态偶尔打断。事实证明他们是有用的加速度数据的可视化偶尔五在一个高频率高否则缓慢移动的手。
个兴味版本的MATLAB代码,我用来制作上面的情节是在接下来的可折叠的块。
关闭所有明确的%如果你的电脑不能运行这个实时,减少样本%的速度或注释掉量图的部分fs = 50;%在50 Hz= arduino (“COM3”、“Uno”,“库”,“I2C”);arduino变化百分比imu = mpu9250(一个);buffer_length_sec = 2;%秒的数据存储在缓冲区accel = 0(地板(buffer_length_sec * fs) + 1, 3);%初始化缓冲t = 0:1 / fs:(buffer_length_sec(结束));%的时间向量次要情节(2,1,1)plot_accel =情节(t, accel);%建立accel阴谋轴([0,buffer_length_sec、-50、50]);次要情节(2,1,2)plot_scale =图像(0 (224、224、3));%建立量图抽搐%开始计时last_read_time = 0;我= 0;% 20秒而(toc < = 20) current_read_time = toc;如果(current_read_time - last_read_time) > = 1 / f i = i + 1;accel (1: end-1,:) = accel (2:,:);%值转变FIFO缓冲区accel(最终:)= readAcceleration (imu);plot_accel (1)。YData = accel (: 1);plot_accel (2)。YData = accel (:, 2);plot_accel (3)。YData = accel (:, 3);%只运行量图第三个示例以节省计算时间如果国防部(我,3)= = 0 fb = cwtfilterbank (SignalLength,长度(t) SamplingFrequency, fs,…“VoicesPerOctave”, 12);sig = accel (: 1);(慢性疲劳综合症,~)= wt (fb,团体);cfs_abs = abs (cfs);accel_i = imresize (cfs_abs / 8, 224 [224]);fb = cwtfilterbank (SignalLength,长度(t) SamplingFrequency, fs,…“VoicesPerOctave”, 12);sig = accel (:, 2);(慢性疲劳综合症,~)= wt (fb,团体); cfs_abs = abs(cfs); accel_i(:, :, 2) = imresize(cfs_abs/8, [224 224]); fb = cwtfilterbank('SignalLength', length(t), 'SamplingFrequency', fs, ... 'VoicesPerOctave', 12); sig = accel(:, 3); [cfs, ~] = wt(fb, sig); cfs_abs = abs(cfs); accel_i(:, :, 3) = imresize(cfs_abs/8, [224 224]); if~(isempty(accel_i(accel_i>1))) accel_i(accel_i>1) = 1; end plot_scale.CData = accel_i; end last_read_time = current_read_time; end end
注意,这段代码使用一个函数调用cwtfilterbank创建量图的一部分小波工具箱。如果你无法访问这个工具箱,你自己不想写代码,试着给另一种类型的时频可视化。也许是一个光谱图将工作或其他你提出的算法。无论你选择什么,这里的想法是,我们试图创建一个图像,这将使高5模式的独特的和可识别的特征明显。我已经表明,量图的工作原理,但其他方法可能的工作。
创建的训练数据
训练一个网络识别的击掌,我们需要多个例子的高5的样子和五看起来不像。因为我们将从pre-trained网络,我们不需要尽可能多的训练例子我们如果我们从头培训网络。我不知道需要多少训练数据完全捕获所有可能的解决方案空间击掌吧,然而,我收集的数据为100和100 non-high击掌5,似乎工作得很好。我怀疑我可以侥幸不视频我,但我想如果我真的是创建一个产品我就会使用更多的例子。你可以在标签的训练数据的数量,看看它如何影响结果。
收集200张图片好像很多工作,但是我写了一个脚本,该脚本循环通过它们一个接一个,保存在适当的图像文件夹。我跑两次下面的脚本;一旦与“high_five”标签图片被保存到数据/ high_five文件夹一旦与“no_high_five”标签的图片被保存到数据/ no_high_five文件夹中。
%这个脚本收集训练数据,在指定的地方子文件夹%标签。3秒的数据被收集%传感器只有保持和保存了最后2秒。%这给用户一些缓冲时间开始高5。%之间的程序暂停图片和提示用户继续。%,你要把这图从MATLAB窗口%之后你可以看到加速度响应的等待提示。关闭所有清除所有%如果你的电脑不能运行这个实时,降低采样率fs = 50;%在50 HzparentDir = pwd;dataDir =“数据”;% %的标签数据集生成%标签=“no_high_five”;标签=“high_five”;= arduino (“COM3”、“Uno”,“库”,“I2C”);arduino变化百分比imu = mpu9250(一个);buffer_length_sec = 2;%秒的数据存储在缓冲区accel = 0(地板(buffer_length_sec * fs) + 1, 3);%初始化缓冲t = 0:1 / fs:(buffer_length_sec(结束));%的时间向量次要情节(2,1,1)plot_accel =情节(t, accel);%建立accel阴谋轴([0 buffer_length_sec -50 50]);次要情节(2,1,2)plot_scale =图像(0 (224、224、3));%建立量图j = 1:10 0%收集100张图片%提示用户准备记录下高5H =输入(“回车当准备好了:”);抽搐%开始计时last_read_time = 0;我= 0;% 3秒而(toc < = 3) current_read_time = toc;如果(current_read_time - last_read_time) > = 1 / f i = i + 1;accel (1: end-1,:) = accel (2:,:);%在缓冲区移值accel(最终:)= readAcceleration (imu);plot_accel (1)。YData = accel (: 1);plot_accel (2)。YData = accel (:, 2);plot_accel (3)。YData = accel (:, 3);%运行每3日量图示例如果国防部(我,3)= = 0 fb = cwtfilterbank (SignalLength,长度(t) SamplingFrequency, fs,…“VoicesPerOctave”, 12);sig = accel (: 1);(慢性疲劳综合症,~)= wt (fb,团体);cfs_abs = abs (cfs);accel_i = imresize (cfs_abs / 8, 224 [224]);fb = cwtfilterbank (SignalLength,长度(t) SamplingFrequency, fs,…“VoicesPerOctave”, 12);sig = accel (:, 2);(慢性疲劳综合症,~)= wt (fb,团体); cfs_abs = abs(cfs); accel_i(:, :, 2) = imresize(cfs_abs/8, [224 224]); fb = cwtfilterbank('SignalLength', length(t), 'SamplingFrequency', fs, ... 'VoicesPerOctave', 12); sig = accel(:, 3); [cfs, ~] = wt(fb, sig); cfs_abs = abs(cfs); accel_i(:, :, 3) = imresize(cfs_abs/8, [224 224]); if~(isempty(accel_i(accel_i>1))) accel_i(accel_i>1) = 1; end plot_scale.CData = accel_i; end last_read_time = current_read_time; end end%保存图像数据文件夹imageRoot = fullfile (parentDir dataDir);imgLoc = fullfile (imageRoot char(标签);imFileName = strcat (char(标签),“_”,num2str (j) . jpg);imwrite (plot_scale。CData, fullfile (imgLoc imFileName)的JPEG);结束
手动运行脚本后,我经历了我的训练数据和删除图片,我认为腐败的培训。这些图像的高5不是中间的框架或图片,我知道我做了一个可怜的高5个运动。低于gif,我删除高5图像49因为它没有中心的框架。
学习和GoogLeNet转移
我所有的训练数据的适当的文件夹,下一步是建立网络。对于这部分,我是跟随了MATLAB的例子时间序列分类使用小波分析和深度学习,除了,而不是通过MATLAB脚本运行一切,我发现它更容易建立和培养网络使用深层网络设计师应用程序。
我开始从pre-trained GoogLeNet利用所有的知识网络在图像识别对象。GoogLeNet被训练识别鱼和热狗的图像——显然不是我寻找的东西——但这就是转移学习是有用的。转移学习,我可以保持现有的网络,只有更换两层的网络,这些通用的特性结合到我在寻找特定模式。然后我重新训练网络时,它几乎只是这两个层需要训练,这就是为什么训练是学习所以更快的转移。
我建议你跟随我使用MATLAB例子或者看科技讨论如果你想知道如何我取代了层和训练参数使用,然而,这又是一个很好的地方让你尝试不一样的东西。你可以试着从一个不同的像SqueezeNet pretrained网络,或者你可以在GoogLeNet取代更多的层,或改变训练参数。这里有很多的选择,我认为偏离我所做的能帮你开发一些直觉,所有这些变量如何影响结果。
培训网络
网络准备好,训练在深层网络设计师应用程序非常简单。在data选项卡,我导入了训练数据通过选择文件夹我救了的高5和5个图片。我也留出20%的图像用于验证在训练过程中。
然后在训练选项卡,我把培训选项。在这里,我是使用相同的选项中使用MATLAB的例子后,然而,再次我鼓励你们其中的一些价值观和查看他们如何影响结果。
培训仅用了4分钟在我的单CPU和验证准确性达到97%左右。不太坏了几小时的工作!
测试高5个计数器
现在,我有一个训练网络,我使用的函数分类量图的深度学习工具箱通过在每个样本时间和网络返回一个标签。如果返回的标签是“high_five”我增加一个计数器。保持五几次从数相同的高加速度数据有整个缓冲区,我添加了一个超时,不会数新高五,除非它已经至少2秒前高5。
下面是一个清理版本的代码,我用来计数的击掌。
关闭所有明确的% %更新你的训练网络的名称负载trainedGN trainedNetwork = trainedGN;%如果你的电脑不能运行这个实时,减少样本%的速度或注释掉量图的部分fs = 50;%在50 Hz= arduino (“COM3”、“Uno”,“库”,“I2C”);arduino变化百分比imu = mpu9250(一个);buffer_length_sec = 2;%秒的数据存储在缓冲区accel = 0(地板(buffer_length_sec * fs) + 1, 3);%初始化缓冲t = 0:1 / fs:(buffer_length_sec(结束));%的时间向量%设置情节h =图;h。位置= (100 100 900 700);p1 =次要情节(2,1,1);plot_accel =情节(t, accel);plot_accel (1)。线宽= 3;plot_accel (2)。线宽= 3;plot_accel (3)。LineWidth = 3; p1.FontSize = 20; p1.Title.String = 'Acceleration'; axis([0 t(end) -50 60]); xlabel('Seconds'); ylabel('Acceleration, mpss'); grid on; label_string = text(1.3, 45, 'No High Five'); label_string.Interpreter = 'none'; label_string.FontSize = 25; count_string = text(0.1, 45, 'High five counter:'); count_string.Interpreter = 'none'; count_string.FontSize = 15; val_string = text(0.65, 45, '0'); val_string.Interpreter = 'none'; val_string.FontSize = 15; p2 = subplot(2, 1, 2); scale_accel = image(zeros(224, 224, 3)); p2.Title.String = 'Scalogram'; p2.FontSize = 20; telapse = 0; hfcount = 0; tic%开始计时last_read_time = 0;我= 0;%运行高5个计数器,持续20秒而(toc < = 20) current_read_time = toc;如果(current_read_time - last_read_time) > = 1 / f i = i + 1;telapse = telapse + 1;%读accelaccel (1: end-1,:) = accel (2:,:);%值转变FIFO缓冲区accel(最终:)= readAcceleration (imu);plot_accel (1)。YData = accel (: 1);plot_accel (2)。YData = accel (:, 2);plot_accel (3)。YData = accel (:, 3);%只运行量图第三个示例以节省计算时间如果国防部(我,3)= = 0%量图fb = cwtfilterbank (SignalLength,长度(t) SamplingFrequency, fs,…“VoicesPerOctave”, 12);sig = accel (: 1);(慢性疲劳综合症,~)= wt (fb,团体);cfs_abs = abs (cfs);accel_i = imresize (cfs_abs / 8, 224 [224]);fb = cwtfilterbank (SignalLength,长度(t) SamplingFrequency, fs,…“VoicesPerOctave”, 12);sig = accel (:, 2);(慢性疲劳综合症,~)= wt (fb,团体); cfs_abs = abs(cfs); accel_i(:, :, 2) = imresize(cfs_abs/8, [224 224]); fb = cwtfilterbank('SignalLength', length(t), 'SamplingFrequency', fs, ... 'VoicesPerOctave', 12); sig = accel(:, 3); [cfs, ~] = wt(fb, sig); cfs_abs = abs(cfs); accel_i(:, :, 3) = imresize(cfs_abs/8, [224 224]);% 1饱和像素如果~ (isempty (accel_i (accel_i > 1))) accel_i (accel_i > 1) = 1;scale_accel结束。CData = im2uint8 (accel_i);%量图进行分类(YPred,聚合氯化铝)= (trainedNetwork scale_accel.CData)进行分类;如果比较字符串(字符串(YPred) high_five) label_string。写成BackgroundColor = (1 0 0);label_string。字符串= "高5 !”;%只有计数100个样本过去自去年高5如果telapse > 100 hfcount = hfcount + 1;val_string。字符串(字符串(hfcount);telapse = 0;其他label_string结束。写成BackgroundColor = (1 1 1);label_string。字符串=“五不高”;端端端端
这里在行动!
- 类别:
- 深度学习
评论
留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。