×

使用K210和Arduino IDE/Micropython进行图像识别

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

李艺银

分享资料个

 

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

本质上, aXeleRate是基于我用于训练图像识别/对象检测模型的脚本集合 - 组合成一个框架并针对 Google Colab 上的工作流程进行了优化。使用起来更方便,更新更及时。

对于旧版本的文章,你仍然可以在steemit.com 上看到。

第 1 步:CNN 和迁移学习:一些理论

 
poYBAGNYg5mAMAguAAHmqZXgH9c687.png
 
 
pYYBAGNYg5yAd81JAABkqViSEig281.png
 

卷积神经网络或 CNN 是一类深度神经网络,最常用于分析视觉图像。互联网上有很多关于该主题的文献,我将在文章的最后部分提供一些链接。简而言之,您可以将 CNN 视为一系列应用于图像的过滤器,每个过滤器在图像中寻找特定的特征——在较低的卷积层上,特征通常是线条和简单的形状,而在较高层上的特征可以更具体,例如身体部位、特定纹理、动物或植物的部分等。某些特征集的存在可以为我们提供关于图像中对象可能是什么的线索。胡须,两只眼睛和黑鼻子?一定是猫!绿叶,树干?看起来像一棵树!

我希望您现在了解 CNN 的工作原理。通常,深度神经网络需要数千张图像和数小时的训练时间(取决于您用于训练的硬件)来“开发”可用于识别您想要的对象类型的过滤器。但有一条捷径。

一个被训练来识别很多不同的常见物体(猫、狗、家用电器、交通工具等)的模型已经“开发”了很多有用的过滤器,所以我们不需要它来学习识别基本形状和对象的一部分。我们可以重新训练网络的最后几层来识别特定类别的对象,这对我们很重要。这被称为“迁移学习”。通过迁移学习,你需要的训练数据和计算时间要少得多,因为你只训练网络的最后几层,可能由几百个神经元组成。

听起来很棒,对吧?让我们看看如何实现它。

第 2 步:准备环境

poYBAGNYg56AQcJoAAFHNaoL3vE378.jpg
 

使用 aXeleRate 有两种方法:在 Ubuntu 机器上本地运行或在 Google Colab 中运行。要在 Google Colab 中运行,请查看以下示例:

图片分类 Colab Notebook

现在在本地训练您的模型并将其导出以用于硬件加速也变得更加容易。

我的工作环境是 Ubuntu 16.04,64 位。您可以使用虚拟机来运行 Ubuntu 映像,因为我们不会使用 GPU 进行训练。通过一些修改,您还可以在 Windows 上运行训练脚本,但是对于模型转换,您需要使用 Linux 系统。因此,您执行本教程的首选环境是 Ubuntu 16.04,在本机或虚拟机中运行。

让我们从安装 Miniconda 开始,它是 Python 的环境管理器。我们将创建隔离环境,因此我们不会意外更改您系统 Python 环境中的任何内容。

在此处下载安装程序

安装完成后,新建环境:

conda create -n ml python=3.7

让我们激活新环境

conda activate ml

bash shell 前的前缀将与环境名称一起出现,表明您现在在该环境中工作。

第 3 步:安装 aXeleRate 并运行测试

pYYBAGNYg6GAPeTjAAHqMgZsLcw604.png
 

在本地机器上安装 aXeleRate

pip install git+https://github.com/AIWintermuteAI/aXeleRate

要下载示例,请运行:

git clone https://github.com/AIWintermuteAI/aXeleRate

您可以使用 aXeleRate 文件夹中的 tests_training.py 运行快速测试。它将为每种模型类型运行训练和推理,保存和转换训练好的模型。由于它只训练 5 个 epoch 并且数据集非常小,您将无法获得有用的模型,但此脚本仅用于检查是否存在错误。

第 4 步:重新训练模型,将 Keras 模型转换为 Kmodel

poYBAGNYg6OALBDNAAB6Hw5UMuo529.jpg
 

对于这个玩具示例,我们将训练模型识别圣诞老人和 Arduino Uno。显然你可以选择其他类。从这里下载数据集在 config 文件夹中创建一个 classifier.json 文件的副本,然后进行相应的更改,类似于屏幕截图中的配置文件 - 确保训练和验证文件夹的路径正确!

从 aXeleRate 文件夹运行以下命令:

python axelerate/train.py - c configs/santa_uno.json

培训将开始。如果验证准确度(我们的验证指标)在 20 个 epoch 内没有提高,训练将提前停止。每次验证准确性提高时,模型都会保存在项目文件夹中。训练结束后,aXeleRate 自动将最佳模型转换为指定格式 - 您现在可以选择“tflite”、“k210”或“edgetpu”。

第 5 步:在 Sipeed Maix Bit 上运行模型

有两种方法可以在 Sipeed Maix 硬件上运行您现在拥有的模型:micropython 固件和 Arduino IDE。Micropython 硬件更易于使用,但它占用了很大一部分可用内存,因此留给模型的空间更少。Arduino IDE 基本上是 C 代码,效率更高,内存占用更小。我的模型只有 1.9Mb,所以两个选项都适用。您可以将 2.9 Mb 的模型与 Micropython 一起使用,对于需要考虑使用 Arduino IDE 的任何更大的模型。

从这里下载 OpenMV IDE 和从这里下载最小的 micropython固件

使用kflash_gui 工具烧录固件。 您也可以选择将训练好的模型也刻录到 flash,如屏幕截图所示。

pYYBAGNYg6aAZ7tMAADN0KRTIBk428.jpg
 

或将其复制到 SD 卡(在这种情况下,将.kmodel复制到 SD 卡的根目录并将 SD 卡插入 Sipeed Maix Bit)

打开 OpenMV IDE 并按下连接按钮。从 example_scripts 文件夹打开santa_uno.py脚本,然后按开始按钮。您应该会看到来自相机的实时流,如果您打开串行终端,您将获得置信度得分最高的图像识别结果!

poYBAGNYg6iAcOZTAADvTU6lyQU222.jpg
 

要与 Arduino IDE 一起使用,首先您需要按照将 Sipeed 板添加到 Arduino IDE 的过程进行操作,此处记录。添加板后,打开mobilenet_v1_transfer_learning.ino草图并将其上传到 Sipeed Maix Bit。将 SD 卡上的模型名称更改为“模型”(或使用此名称复制)。

poYBAGNYg6uAGJ5NAACLQcM8_kA252.jpg
 

您可以更改names.cpp中的标签名称它将在 Sipeed Maix 屏幕上显示实时摄像机流以及顶部图像识别结果。

第 6 步:结论

 

以下是有关 CNN 和迁移学习主题的更多材料可供阅读:

使用 Mobilenet 和 Keras进行迁移学习迁移学习的一个很好的解释,本教程使用该文章中代码的修改版本。

猫狗和卷积神经网络解释 CNN 背后的基础知识并可视化一些过滤器。与猫!

在 Sipeed MaixPy 和 MaixDuino 上训练、转换、运行 MobileNet!Sipeed 团队关于如何从头开始训练 Mobilenet 1000 类的教程(无迁移学习)。您可以下载他们的预训练模型并尝试一下!

希望您可以利用您现在拥有的知识来构建一些带有机器视觉的很棒的项目!你可以在这里购买 Sipeed 板,它们是嵌入式系统上机器学习最便宜的选择之一。

如果您有任何问题,请在LinkedIn上添加我,并订阅我的 YouTube 频道,以获得有关机器学习和机器人技术的更多有趣项目的通知。


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

评论(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:'使用K210和Arduino IDE/Micropython进行图像识别',//标题 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);