×

TinyML课程#7变得更小

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-06-25

安德森大

分享资料个

描述

这是 TinyML 课程系列的最后一篇文章——在之前的文章中,我们已经讨论了如何训练和部署机器学习模型,用于音频场景分类异常检测语音识别和其他任务到 Wio Terminal,一个紧凑的生产就绪开发板来自 Seeed 工作室。

 

2022 年 3 月 29 日更新我尽我所能定期更新我的文章,并根据您在 YouTube/Hackster 评论部分的反馈。如果您想表达对这些努力的支持和赞赏,请考虑给我买杯咖啡(或披萨):)

Wio Terminal 虽然由于存在多个内置传感器和一个外壳而便于实验,但对于某些应用(例如可穿戴设备)来说可能有点过于笨重。在最后一个项目中,我们甚至会使用 Tinier 并使用 Seeeduino XIAO 板——即原始 XIAO和更新的XIAO 2040 ,并将简要提及即将发布的XIAO BLE

 

Specks-wise, 最初的 XIAO 在发布时可能是最小的 M0 开发板,它的尺寸与 ARM® Cortex®-M0+ 48MHz 微控制器 (SAMD21G18) 和 256KB 闪存、32KB SRAMOriginal XIAO 相得益彰——就像你可以看到它比拇指指甲大一点。

poYBAGNYkmuARUgoAABEH-OTymU629.png
Original XIAO – 如您所见,它比拇指指甲大一点。
 

后来 RP2040 芯片问世并提供了更好的规格 Cortex M0+ 设计。两者都非常有能力运行我们将用于该项目的微型神经网络,但如果您有一些要求更高的应用程序,那么选择 XIAO RP2040 而不是原来的 XIAO 确实有意义。

pYYBAGNYkm-ARBCNAAD0sGxz1i0994.jpg
 

作为一名软件工程师,我肯定和你们中的许多人一样,会花很多时间在我椅子上发光的屏幕前。而在当天晚些时候,保持适当的姿势变得困难。

poYBAGNYknGAegHXAABPZWG4zTs014.png
 

如果有一种方法可以制造一种设备,该设备可以学习您的特定身体姿势以正确和错误的姿势,并在您过度无精打采或进入“蟒蛇姿势”时警告您……等一下,有!

为机器学习模型提供数据的任务的最佳传感器显然是加速度计。XIAO 系列的所有板子都非常小,没有配备加速度传感器。虽然我们可以使用XIAO 扩展板进行开发和测试,但它消除了 XIAO 板具有的低占用空间优势。如果您要创建自己的产品,更好的选择是为芯片或 SoM 创建自己的定制 PCB 板。我请我们的硬件工程师为 XIAO 设计一个简单的载板,其中包括 LIS3DH 加速度计、蜂鸣器和带电源开关的电池连接器。

poYBAGNYknWALZY1AAW1f-hOfHY257.png
 

然后我们使用 Seeed studio Fusion 服务打印了一些 PCBA 样本——为此,请访问https://www.seeedstudio.com/fusion_pcb.html并上传 Gerber 文件,其中包含 PCB 设计并为威廉希尔官方网站 板选择适当的参数,例如如层数、基材、最小钻孔尺寸等。我们可以看到,一个简单的 2 层板 10 块加上运费约为 4.9 美元。

poYBAGNYkneAL2rTAACpmtoePD8725.png
 

如果您想在没有定制 PCB 的情况下重复实验,您可以将Grove LIS3DH加速度计模块连接到 XIAO 扩展板并开始收集数据。我为每个姿势收集了 3 个数据样本,每个 60 秒,设备附在我背上的 T 恤上。

pYYBAGNYknqANcchAADU0LSVP7k951.png
 

对于每个样本,我保持相同的姿势,但包括一些手臂、头部和躯干的运动来模拟正常活动。

我选择了 5 秒的时间窗口和 1 秒的窗口偏移和展平处理块,因为我们正在处理非常缓慢的移动数据。一个非常简单的全连接网络提供了良好的准确性。这是Edge Impulse 项目的公共版本的链接。

pYYBAGNYkoCAX-6eAAC1a1V9TwU074.png
 

通过收集更多数据并确保可以识别正确和不正确的姿势,可以通过衣服上的设备定位的一些变化来做出一些改进。由于该设备被认为是个人使用设备,因此无需推广到不同人的姿势,并且可以轻松地重新训练。您可以在实时分类选项卡中检查训练后它检测您的姿势的能力。

在您对准确性感到满意后,将生成的模型下载为 Arduino 库并将其复制到您的 Arduino 草图/库文件夹中。您可以下载示例代码,该代码将收集 5 秒的样本,执行推理并在检测到其中一个不正确的姿势时打开蜂鸣器。

void loop()
{

    ei_printf("Sampling...\n");

    // Allocate a buffer here for the values we'll read from the IMU
    float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };

    for (size_t ix = 0; ix < EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE; ix += 3) {
        // Determine the next tick (and then sleep later)
        uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);

        lis.getAcceleration(&buffer[ix], &buffer[ix+1], &buffer[ix + 2]);
        buffer[ix + 0] *= CONVERT_G_TO_MS2;
        buffer[ix + 1] *= CONVERT_G_TO_MS2;
        buffer[ix + 2] *= CONVERT_G_TO_MS2;

        delayMicroseconds(next_tick - micros());
    }

    // Turn the raw buffer in a signal which we can the classify
    signal_t signal;
    int err = numpy::signal_from_buffer(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
    if (err != 0) {
        ei_printf("Failed to create signal from buffer (%d)\n", err);
        return;
    }

    // Run the classifier
    ei_impulse_result_t result = { 0 };

    err = run_classifier(&signal, &result, debug_nn);
    if (err != EI_IMPULSE_OK) {
        ei_printf("ERR: Failed to run classifier (%d)\n", err);
        return;
    }

    // print the predictions
    ei_printf("Predictions ");
    ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",
        result.timing.dsp, result.timing.classification, result.timing.anomaly);
    ei_printf(": \n");
    for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
        ei_printf("    %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
    }
#if EI_CLASSIFIER_HAS_ANOMALY == 1
    ei_printf("    anomaly score: %.3f\n", result.anomaly);
#endif
    
  if (result.classification[1].value > ALARM_THRESHOLD || result.classification[2].value > ALARM_THRESHOLD)
  {     
  tone(BUZZER_PIN, 523, 250);
  delay(250);
  noTone(BUZZER_PIN);
  delay(250);  
  tone(BUZZER_PIN, 523, 250);
  delay(250);  
  noTone(BUZZER_PIN);    
  }

}

由于它是相对缓慢变化的数据,我们不需要快速的响应时间,正常的顺序推理管道非常适合这个应用程序。

上面的一个步骤是使用最新的 XIAO BLE 并将设备连接到用户的智能手机,这将允许更好的警报、统计等。

poYBAGNYkoOAXYCmAADZ8of_Gfc391.png
 

即将发布的 Seeeduino BLE 有两个版本:BLE 和 BLE Sense。在 SBC 和服务器上执行了更大的 ML 模型之后,在最小的设备上修补机器学习对我来说确实是一次令人大开眼界的体验。如果您想继续学习该主题,请查看Coursera 和 Edge Impulse 提供的免费课程,以及Codecraft,这是一种图形编程环境,允许创建 TinyML 应用程序并将其部署到 Wio Terminal。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'TinyML课程#7变得更小',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);