1 在MaaXBoard RT上运行几乎任何TensorFlow模型-德赢Vwin官网 网
×

在MaaXBoard RT上运行几乎任何TensorFlow模型

消耗积分:2 | 格式:zip | 大小:5.75 MB | 2022-10-31

分享资料个

描述

设置

电路板设置

  • 将 MaaXBoard 摄像头插入音频插孔旁边的 MIPI-CSA 摄像头连接器。
  • 将显示器插入电路板背面的 MIPI-DSI 连接器
  • 将 MCU 链路插入 JTAG 连接器。如图所示,将接地、TXD 和 RXD 引脚连接到 MaaXBoard RT 上的 Pi 接头。将 MCU 链接的另一端插入主机 PC 的 USB 端口。
  • 将 5V、3A 电源连接到 MaaXBoard 上的 USB-C 端口为其供电。
 
 
 
pYYBAGNY3-2AFBSnABUOqo8dWQU645.jpg
 
1 / 3将 MaaXBoard 摄像头插入音频插孔旁边的 MIPI-CSA 摄像头连接器。
 

我建议为您的 MIPI 相机创建一个支架,以便轻松定位以识别物体。我的是用 OpenBeam 做的,但你可以用木头、冰棒棍和电工胶带,或者你周围的任何东西。

软件设置

  • 在您的计算机上下载并安装最新版本的MCUXpresso IDE 。您需要一个恩智浦帐户。他们有适用于 Windows、Mac 和 Linux 的二进制文件。
  • 登录NXP SDK Builder ,点击“Select Development Board”,搜索 RT1170 以找到i.MX RT 1170 SDK 注意:MaaXBoard RT 自定义 SDK 即将发布。
  • 通过将 SDK 拖放到 MCUXPresso 的“已安装的 SDK”部分来安装 SDK
  • 下载这个项目的代码(在代码部分找到它)
  • 点击 MCUXpresso 中的“import project(s) from file system”,导入刚刚下载的压缩文件
  • 选择项目,点击“下一步”,点击“完成”即可导入刚刚下载的项目
 
 
 
poYBAGNY3_CAf17XAAE3bzhZInM404.png
 
1 / 11
 

测试示例代码

  • 选择“调试”以构建代码并将其加载到您的板上。
  • 如果这是您第一次调试项目,则必须从找到的调试探针列表中选择“启动配置”。选择调试探针并且用户单击“确定”后,IDE 将自动为该调试探针创建默认启动配置文件。
  • 选择“运行”。您应该会在 LCD 上看到摄像头图像。尝试将物体放在相机前,看看您的模型是否会检测到它们。您可以在MaaX_v2_tensorflow_lite_micro_label_image_cm7 > doc > labels.txt下查看可检测对象的完整列表有些物品可能很难找到(例如,我碰巧没有欧洲火蝾螈)。然而,橙子在名单上,它们似乎工作正常。
pYYBAGNY3_KAfSBTAACHgVoPSz8268.png
 

包含的模型是 i.MX SDK eIQ 示例中包含的 Mobilenet v.1 的默认版本。虽然快速且轻巧,但它不是很准确。您会看到它通常无法识别图像中的任何内容:

Inference time: 172 ms

Detected: No label detected (0%)

这里列出了一个有用的 Tensorflow Lite 图像分类模型列表,以及它们的准确性、速度(以四核 CPU 为基准)和大小。我们使用的默认模型与列表中的第一个模型最相似。它的 top-1 准确率为 39.5%,这意味着模型的最高预测只有大约 39.5% 的时间是正确的标签。

选择新模型和/或数据集

在这里,我们的任务是图像分类,所以我们只考虑图像分类模型。I.MX RT 板有几种不同的模型类型示例:

pYYBAGNY3_aAKHG8AADzBDLLBrw009.png
 

根据您的图像分类需求,您可能需要具有一定准确性或速度的模型。确定特定模型是否可以在特定设备上运行基于:

  • 推理运行需要多长时间?相同的模型在功能较弱的设备上运行需要更长的时间。
  • 是否有足够的非易失性内存来存储权重、模型本身和推理引擎?
  • 是否有足够的 RAM 来跟踪模型的中间计算和输出?您可能需要增加堆大小以提高性能。

尽管 MaaXBoard RT 有一个浮点单元并且能够运行浮点模型,但最好对模型进行量化以考虑大小和速度。

大小:MaaXBoard 配备 256 Mb 超闪存。Tensorflow Lite 标签图像项目为 35.4Mb,其中 5.5 个是模型本身。

我可以从 Tensorflow Lite 模型列表中看到,量化 MobileNet v2 比 V1 准确得多,同时仍然相当小且速度快:

pYYBAGNY3_iAMK9sAAASUWm9zw8810.png
 

重新训练您的模型(可选)

您可以按原样使用该模型,或者如果您希望在自定义数据集上对其进行训练,您可以使用迁移学习来重新训练您的模型。

迁移学习的完整说明在此处的恩智浦迁移学习实验室中,您可以在此处找到与迁移学习实验室相关的更多信息,了解如何收集或选择数据您需要一个带标签的图像数据集进行训练(最好使用 MaaXBoard RT 相机收集的数据进行训练),并且您还需要在您的 PC 上安装正确版本的 Python 和 Tensorflow。

转换您的模型以在 MCUXpresso 中使用

在这一步中,我们将把我们的模型转换为 C 头文件,这些头文件可以添加到 MCUXpresso 中的项目中,然后加载到 MaaXBoard RT 上。这其实很简单。它只需要 Vim,如果你在 Mac 或 Linux 上应该已经可用。

如果在 Windows 上,请安装Vim 8.1 :在该软件包内有一个名为 xxd.exe 的二进制转换程序,需要名为 xxd。xxd 是一个 hexdump 实用程序,可用于在文件的十六进制转储和二进制形式之间来回转换。在这种情况下,该实用程序用于将 tflite 二进制文件转换为可添加到 eIQ 项目的 C/C++ 头文件。

  • 安装后,将 vim 添加到您的可执行 PATH(如果还没有的话):
 
 
 
poYBAGNY3_uAczxdAABnecaPa3w485.png
 
1 / 4
 
  • 通过打开 Windows 命令提示符并在命令提示符中键入“xxd -v”来验证 PATH 设置是否正确。您不应收到有关无法识别的命令的任何错误。
  • 使用 xxd 实用程序将 .tflite 二进制文件转换为可导入嵌入式项目的 C 数组。

如果使用 Windows 命令提示符:

xxd -i mobilenet_v2_1.0_224_quant.tflite > model_data.h

如果使用 Windows Powershell:

xxd -i mobilenet_v2_1.0_224_quant.tflite | out-file -encoding ASCII mobilenet_v2_1.0_224_quant.h
  • 该模型需要稍作修改以将其集成到 MCUXpresso SDK 中。打开model_data.h文件并对文件顶部进行以下更改。还要记下数组名称,因为它将在下一节中使用:

#include

#define MODEL_NAME "mobilenet_v1_0.25_128_quant_int8"

#define MODEL_INPUT_MEAN 127.5f

#define MODEL_INPUT_STD 127.5f

const char model_data[] __ALIGNED(16) = {

更改后应如下所示:

pYYBAGNY3_2AH8l1AABEBQaQziM973.png
 

转换您的标签

如果您使用的是现有模型,它应该带有一个labels.txt文件(在 mobilenet 的情况下,它被称为 mobilenet_labels.txt)。附加的 python 脚本,replace_label_text.py,应该将一个正常的行分隔的labels.txt文件转换为与 C++ 一起工作的文件。将您的文件命名为“ labels.h

转换后,它应该如下所示:

pYYBAGNY3_-AVJHeAAAYEYr8OTg102.png
 

修改示例项目

最后一步是采用TensorFlow Lite Label Image示例并对其进行修改以使用新重新训练的模型。

将模型和标签文件导入 MCUXpresso

我们需要将上一节中生成的模型文件model_data.h和标签文件labels.h都导入到这个项目中。

  • 通过右键单击项目名称找到此示例复制到的目录位置,然后选择Properties 在出现的对话框中,单击图标以在 Windows 资源管理器中打开该目录。
  • 转到刚刚打开的MaaX_v2 _ tensorflow_lite_micro_label_image_cm7文件夹中的“源”目录。它应该类似于:C:\Users\nxp_training\MCUXpressoIDE_11.3.0_0522\workspace\MaaX_v2 _ tensorflow_lite_micro_label_image_cm7\source\model
  • 在该模型目录中,复制上一节中生成的model_data.h文件和labels.h文件。这些文件将替换现有的 model_data.h 和 labels.h 文件。完成后目录应如下所示:
 
 
 
pYYBAGNY4AaAStV1AACMIDA_62w238.png
 
1 / 2
 

修改示例源代码

双击项目视图中“source\model”文件夹下的model.cpp文件将其打开。

第 15 和 16 行应该引入模型和您的新模型 model_data.h:

pYYBAGNY4AiAd0_PAAAK2N2hXKY847.png
 

在第 26 行左右,更改 API 调用以加载默认模型,并将其替换为新头文件中的新模型名称 (model_data) 和模型长度 (model_data_len)。它可能与下面列出的名称略有不同。它应该与 model_data.h 中的数组名称和长度相匹配( const char model_data[] __ALIGNED(16) = {):

pYYBAGNY4AuAAp8BAAAu5W7NEmQ909.png
 

为了减小项目的大小,Label Image示例仅支持默认 Mobilenet 模型所需的特定操作数。我们重新训练的模型使用了一些新的操作数。这些特定的操作数可以通过使用名为netron的应用程序分析模型来确定,然后手动添加操作数,如 eIQ TensorFlow Lite 库用户指南第 7.1 节所述。或者,可以使用 BuiltinOpResolver 方法在项目中支持所有 TFLite 操作数。对于本实验,我们将使用后一种方法,以提供与其他模型的最大兼容性。在model.cpp的第 33 或 34 行附近,注释掉原来的解析器行。然后添加一个新行

tflite::AllOpsResolver micro_op_resolver;

 
 
 
pYYBAGNY4A2AJDGDAAAO5MgQjkk087.png
 
1 / 2
 

这就是您需要进行的所有修改!该应用程序现在可以运行了。

运行演示

在 MCUXpresso 中,确保超闪存驱动程序MaaXBoard_S26KS256.cfx位于Project Explorer下的 xip 文件夹中然后,单击“编辑项目设置”,导航到 MCU 设置,并确保在两个位置都选择了超闪存驱动程序作为闪存驱动程序。

 
 
 
poYBAGNY4A-ACvH5AABFh3KqxfY945.png
 
1 / 3确保超闪存驱动程序 MaaXBoard_S26KS256.cfx 位于 Project Explorer 下的 xip 文件夹中
 

我选择了Debug ,因为这一步即可构建和调试项目。几乎立即(哇,有 HyperFlash!)我能够在 LCD 上看到相机的输出。

我收集了label.h 中命名的东西的列表,例如橙子和一杯葡萄酒(下一次我将训练一个识别鸡尾酒类型的模型,因为这将使测试步骤更加愉快)。

当控制台以 115200 波特打开时,我可以看到它打印每个对象的标签,因为我将它举到相机上,并且模型识别了它:

 
 
 
pYYBAGNY4BiAaZzUABQzcJAz9mY285.jpg
 
1 / 2检测到:橙色 (61%)
 

Inference time: 2537 ms

Detected: orange (61%)

----------------------------------------

Inference time: 2536 ms

Detected: red wine (54%)

----------------------------------------

虽然它比示例项目中提供的 MobileNet 模型慢了一点,但它的准确度要高得多,而且速度仍然足够快,可以派上用场。在这个令人难以置信的微控制器上准备和运行模型的简单程度给我留下了深刻的印象。


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

评论(0)
发评论

下载排行榜

全部0条评论

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

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"//www.hzfubeitong.com/m/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="https://m.elecfans.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:'在MaaXBoard RT上运行几乎任何TensorFlow模型',//标题 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.hzfubeitong.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);