×

使用Sipeed MaiX板进行对象检测(Kendryte K210)

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

h1654155957.9520

分享资料个

描述

 

作为我之前关于使用 Sipeed MaiX 板进行图像识别的文章的延续,我决定写另一个教程,重点是对象检测。但请记住,我不是 Kendryte 或 Sipeed 开发团队的成员,无法回答与他们的产品相关的所有问题。本质上, aXeleRate是基于我用于训练图像识别/对象检测模型的脚本集合 - 组合成一个框架并针对 Google Colab 上的工作流程进行了优化。使用起来更方便,更新更及时。

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

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

第 1 步:对象检测模型架构说明

 
 
 
 
pYYBAGNYg76ALxNsAABgsr3QguE376.jpg
 
1 / 3
 

图像识别(或图像分类)模型将整个图像作为输入,并输出我们试图识别的每个类别的概率列表。如果我们感兴趣的对象占据了图像的大部分并且我们不太关心它的位置,这将非常有用。但是,如果我们的项目(比如人脸跟踪相机)不仅需要了解图像中对象的类型,还需要了解其坐标,该怎么办。那么需要检测多个对象(例如计数)的项目呢?

这是对象检测模型派上用场的时候。在本文中,我们将使用 YOLO(你只看一次)架构,并重点解释这个特定架构的内部机制。

我们试图确定图片中存在哪些对象以及它们的坐标。由于机器学习不是魔术,也不是“思维机器”,而只是一种使用统计数据优化功能(神经网络)以更好地解决特定问题的算法。我们需要对这个问题进行解释,使其更“可优化”。这里的一个天真的方法是让算法最小化它的预测和对象的正确坐标之间的损失(差异)。只要我们在图像中只有一个对象,这就会很好地工作。对于多个对象,我们采用不同的方法——我们添加网格并让我们的网络预测每个网格中对象的存在(或不存在)。好听,但是仍然给网络留下了太多的不确定性——如何输出预测以及在一个网格单元内有多个中心的对象时该怎么办?我们需要再添加一个约束——所谓的锚。锚点是初始大小(宽度、高度),其中一些(最接近对象大小)将调整为对象大小 - 使用神经网络的一些输出(最终特征图)。

所以,这是一个关于 YOLO 架构神经网络对图像执行对象检测时发生了什么的顶级视图。根据特征提取器网络检测到的特征,对每个网格单元进行一组预测,包括锚点偏移量、锚点概率和锚点类别。然后我们丢弃低概率的预测,瞧!

第 2 步:准备环境

 
poYBAGNYg8CAM_eZAABYjHLDP-Y116.jpg
 

aXeleRate 基于 penny4860 的精彩项目,SVHN yolo-v2 数字检测器。 aXeleRate 将这种在 Keras 中的 YOLO 检测器实现提升到一个新的水平,并使用其方便的配置系统来执行图像识别/对象检测和具有各种后端的图像分割网络的训练和转换。

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

PASCAL-VOC 目标检测 Colab Notebook

现在在本地训练您的模型并将其导出以用于硬件加速也变得更加容易。我强烈建议您在 Anaconda 环境中安装所有必要的依赖项,以使您的项目与其他项目分开并避免冲突。

在此处下载安装程序

安装完成后,新建环境:

conda create -n yolo python=3.7

让我们激活新环境

conda activate yolo

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

在本地机器上安装 aXeleRate

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

然后运行它来下载训练和推理所需的脚本:

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

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

第 3 步:使用 Keras 训练对象检测模型

poYBAGNYg8OACPokAAC0cXAeQ8g202.jpg
 

现在我们可以使用配置文件运行训练脚本。由于 YOLO 目标检测器的 Keras 实现相当复杂,因此我将解释如何配置训练并描述相关模块,而不是解释每个相关的代码,以防您想自己对它们进行一些更改。

让我们从一个玩具示例开始,训练一个浣熊探测器。/config 文件夹内有一个配置文件 raccoon_detector.json。我们选择 MobileNet7_5 作为架构(其中 7_5 是原始 Mobilenet 实现的 alpha 参数,控制网络的宽度)和 224x224 作为输入大小。让我们看一下配置中最重要的参数:

类型是模型前端 - 分类器、检测器或 Segnet
架构是模型后端(特征提取器)

- 全 Yolo - Tiny Yolo - MobileNet1_0 - MobileNet7_5 - MobileNet5_0 - MobileNet2_5 - SqueezeNet - VGG16 - ResNet50

有关锚点的更多信息,请在此处阅读 https://github.com/pjreddie/darknet/issues/568

标签是数据集中存在的标签。重要提示:请列出数据集中存在的所有标签。

object_scale确定对对象预测器置信度的错误预测惩罚多少

no_object_scale确定对非对象预测器的置信度的错误预测惩罚多少

coord_scale确定对错误位置和大小预测(x、y、w、h)的惩罚程度

class_scale决定对错误的类预测惩罚多少

增强- 图像增强、调整大小、移动和模糊图像,以防止过度拟合并在数据集中有更大的多样性。

train_times, validation_times - 重复数据集的次数。如果您有增强功能,则很有用

启用

first_trainable_layer - 如果您使用的是预训练的特征网络,则允许您冻结某些层

现在我们需要下载我在Google Drive上共享的数据集原始数据集),这是一个浣熊检测数据集,包含 150 张带注释的图片。

确保相应地更改配置文件(train_image_folder、train_annot_folder)中的行,然后使用以下命令(来自 aXeleRate 文件夹)开始训练:

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

train.py 从 .json 文件中读取配置并使用 axelerate/networks/yolo/yolo_frontend.py 脚本训练模型。yolo/backend/loss.py 是实现自定义损失函数的地方,yolo/backend/network.py 是创建模型的地方(输入、特征提取器和检测层放在一起)。axelerate/networks/common_utils/fit.py 是实现训练过程的脚本,而 axelerate/networks/common_utils/feature.py 包含特征提取器。如果您打算使用带有 K210 芯片和 Micropython 固件的训练模型,由于内存限制,您可以在 MobileNet(2_5、5_0 和 7_5)和 TinyYolo 之间进行选择,但我发现 MobileNet 提供了更好的检测精度。

由于它是一个玩具示例并且仅包含 150 张浣熊的图像,因此即使没有 GPU,训练过程也应该非常快,尽管准确度远非一流。对于与工作相关的项目,我训练了一个交通标志检测器和一个数字检测器,这两个数据集都包含了数千个训练示例。

第 4 步:将其转换为 .kmodel 格式

poYBAGNYg8aAJolmAAC1_ZipRVY630.jpg
 

使用aXeleRate,模型转换是自动进行的——这可能是与旧版训练脚本最大的不同!另外,您可以将模型文件和训练图整齐地保存在项目文件夹中。此外,我确实发现验证准确度有时无法估计对象检测的模型实际性能,这就是为什么我添加 mAP 作为对象检测模型的验证指标的原因。您可以在此处阅读有关 mAP 的更多信息

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

现在到最后一步,在 Sipeed 硬件上实际运行我们的模型!

第 5 步:在 Micropython 固件上运行

pYYBAGNYg8iAYic5AAFG98LYdFc879.jpg
 

可以使用 C 代码使用我们的对象检测模型运行推理,但为了方便起见,我们将使用 Micropython 固件和 MaixPy IDE 代替。

从这里下载MaixPy IDE和从这里下载 micropython 固件您可以使用 python 脚本 kflash.py 烧录固件或在此处下载单独的 GUI flash 工具。

将 model.kmodel 复制到 SD 卡的根目录,并将 SD 卡插入 Sipeed Maix Bit(或其他 K210 设备)。或者,您可以将 .kmodel 刻录到设备的闪存中。我的示例脚本从闪存读取 .kmodel。如果您使用的是 SD 卡,请更改此行

task = kpu.load(0x200000)

task = kpu.load("/sd/model.kmodel")

打开 MaixPy IDE 并按下连接按钮。从 example_scripts/k210/detector 文件夹打开 raccoon_detector.py 脚本,然后按开始按钮。您应该会看到来自摄像机的实时流,周围有边界框……好吧,浣熊。您可以通过提供更多训练示例来提高模型的准确性,但请记住,它是精灵小模型(1.9 M),并且在检测小物体时会遇到麻烦(由于分辨率低)。

我在上一篇关于图像识别的文章的评论中收到的一个问题是如何通过 UART/I2C 将检测结果发送到连接到 Sipeed 开发板的其他设备。在我的 github 存储库中,您将能够找到另一个示例脚本 raccoon_detector_uart.py,它(您猜对了)检测浣熊并通过 UART 发送边界框的坐标。请记住,用于 UART 通信的引脚因不同的板而异,您需要在文档中自行检查。

第 6 步:总结

Kendryte K210 是用于计算机视觉的坚固芯片,灵活,但可用内存有限。到目前为止,在我的教程中,我们已经介绍了使用它来识别自定义对象、检测自定义对象和运行一些基于 OpenMV 的计算机视觉任务。我知道它也适用于人脸识别,并且经过一些修改,应该可以进行姿势检测和图像分割(例如用于单目深度估计)。随意 fork 我的 GitHub 存储库并自己做一些很棒的事情!

以下是我在编写本教程时使用的一些文章,如果您想了解有关使用神经网络进行对象检测的更多信息,请查看:

边界框物体检测器:了解 YOLO,你只看一次

了解 YOLO(更多数学)

关于 YOLO 对象本地化如何与 Keras 配合使用的温和指南(第 2 部分)

使用 YOLO、YOLOv2 和现在的 YOLOv3 进行实时对象检测

希望您可以利用您现在拥有的知识来构建一些带有机器视觉的很棒的项目!你可以在这里购买 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.lene-v.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:'使用Sipeed MaiX板进行对象检测(Kendryte K210)',//标题 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.lene-v.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);