【ATU Book-i.MX8系列 - TFLite 进阶】 NXP i.MX8M Plus 实现高效 Mobilenet SSD 物体检测

news2024/11/19 14:33:31

NXP i.MX8M Plus 实现高效 Mobilenet SSD 物体检测

一、概述

在 边缘运算(Edge Computing) 领域中,轻量级的模型扮演着举足轻重的角色。因此,如何在有限硬体资源下实现电脑视觉(Computer vision) 应用是个极具挑战性的课题。特别是在效能与准确度之间寻求平衡。在本节中,我们将深入剖析 深度学习(Deep Learning) 领域中一个备受关注的研究方向 :目标识别(Object Detection)。这应用催生了众多神经网路架构的创新,从VGG-19、ResNet、Inception V4到Mobilenet-SSD,到近年来风头正劲的YOLO系列,都是朝着在改进模型大小,来优化准确度与运行速度效能。

NXP i.MX8M Plus处理器凭借其卓越的处理能力和高效的能源管理,已成为物体检测应用的理想选择之一。该处理器内建的高效AI加速器,即 NPU (Neural Processor Unit) 神经网路处理器,能迅速处理复杂的神经网路运算,使目标识别(Object Detection) 的应用能更加快速和精确。为在 边缘运算(Edge Computing) 设备上进行物体检测的首选方案。

开发平台的第一步就是如何建立 NXP 嵌入式系统的开发环境, 若不懂此技术的读者可以阅读此 【ATU Book - i.MX8系列 - OS】NXP i.MX Linux BSP 开发环境架设 来快速布署恩智浦 NXP i.MX8 系列的开发环境,透过此博文或 ATU 一部小编的系列博文,即可轻松实现任何有关 i.MX8 的环境架设 !! 或是想要更快速进入到 NXP 平台的实作中,可以至官方网站下载官方发行的 Linux 映像档(Image) [链接]。

若新读者欲理解更多人工智能、机器学习以及深度学习的资讯,可点选查阅下方博文:

大大通精彩博文    【ATU Book-i.MX8系列】博文索引

TensorFlow Lite 进阶系列博文-文章架构示意图


TensorFlow Lite 进阶系列博文-文章架构示意图
 


二、算法介绍

由于边缘运算(edge computing) 需以轻量、快速、准确为主,故采用神经网路架构最轻量,且有一定识别能力、运行效率极佳的 MobileNet + SSD 架构。由 轻量化网路架构 MobileNet 与 物件检测算法(Single Shot MultiBox Detector, SSD) 组成之应用。

神经网路架构探讨 :

(1)MobileNet

核心概念是利用拆分的概念,将原本的卷积层拆成 深度卷积(Depthwise Convolution) 与 逐点卷积(Pointwise Convolution) 两个部分,称作 深层可分离卷积(Depthwise Separable Convolution) 。以此方式进行运算,能够大幅度减少参数量,以达到加快运算速度。(用途撷取特征)

MobileNet 轻量化概念示意图

MobileNet 轻量化概念示意图, 参考 LaptrihnX 网站

(2)Single Shot Multi-Box Detector, SSD

核心概念是由 金字塔特征结构(Pyramidal Feature Hierarchy) 与 先验框(Prior boxes) 的概念组成。

金字塔特征结构(Pyramidal Feature Hierarchy) :

采用不同大小的特征图检测物件,比如说大特征图检测小物件、小特征图检测大物件。

先验框(Prior boxes) :

让每个特征图上设置不同尺寸、长宽比的先验框,以作为预测框的基准。这能够帮助训练过程时,提供梯度一定程度的范围限制,能够降低一定程度的训练难度。

如下图所示,金字塔特征结构概念就是在每个不同大小的特征层之中,进行预测来判断是否有物件,并总和每个特征层的结果,找出最大可能性的物件

金字塔特征结构(Pyramidal Feature Hierarchy) 示意图

金字塔特征结构(Pyramidal Feature Hierarchy) 示意图, 参考 ResearchGate 网志

如下图所示,为 VGG-19 搭配 SSD 的神经网路架构(Neural Network)。如同上述金字塔特征结构概念,更明确的呈现 SSD 架构的作法。其实就是在 VGG 每一层的输出都装上 检测器(Detector) 与分类器 (Classifier) ,并将每层结果连结至 Fast NMS 来找最佳的物件检测结果 !!

SSD 架构概念示意图

SSD 架构概念示意图, 参考 Medium 网志

换个方式呈现上述概念。如下图所示,说明 SSD 是检测多个物件视窗来找到最佳方案。

SSD 架构概念示意图 - 2 ,

SSD 架构概念示意图 - 2 , 参考 ITREAD 网志

  

MobileNet SSD 实际架构 ( Netron呈现 ) :

如下图所示,为实际 MobileNet SSD模组架构。从右侧灰色栏位可看出 Input 与 Output 资讯。依设计所代表输入端为彩色影像、输出端依序分别为物件位置、种类、分数、数量等资讯。亦可从架构图上看到在最后每个输出层有延伸出 “Pyramidal Feature Hierarchy 结构” 。

实际 MobileNet SSD模组架构


三、算法实现

Google 官方有提供效果极佳的 mobilenet_object_detector.tflite 模组,即可直接使用,请点选下载。故这里利用迁移学习方法与 TF-Slim实现 TOTORO 物件检测器(Object Detector)。

实现步骤如下:

第一步 : 开启 Colab 设定环境
%tensorflow_version 1.x
!python -c 'import matplotlib as tf; print(tf.__version__)' # Check the version of the tensorflow

由于 colab 已暂停支援 Tensorflow 1.x 的方式,请本机方式实现。

第二步 :  TensorFlow Model Garden 下载与安装
%cd root
!git clone https://github.com/tensorflow/models.git
%cd root/models/research/
!protoc object_detection/protos/*.proto --python_out=. # gernate *.proto
!python setup.py build  # 建置 TensorFlow Model Garden 档案​

第三步 :  TensorFlow  Slim 下载与安装
import os
os.environ['PYTHONPATH'] += ':/root/models/research/:/root/models/research/slim/:/root/models/research/object_detection/utils/:/root/models/research/object_detection'
!pip install tf_slim # 安装 TensorFlow  Slim
!python object_detection/builders/model_builder_test.py   # TensorFlow  Slim 模组建立是否成功测试

 

第四步 : 下载资料库

***常见的物件识别的资料库为 COCO DataSets

%cd /root/models/
!git clone https://github.com/fllay/totoro.git #Download TOTORO

 

第五步 : 数据特征处理

此步骤须将事先把物件的位置特征与分类资讯纪录于 xml 之中,如下图所示。

参考 GitHub 网站

import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET

# 将 xml 档资料转换成 DataFrame 形式
def xml_to_csv(path):
    xml_list = []
    for xml_file in glob.glob(path + '/*.xml'):
        tree = ET.parse(xml_file)
        root = tree.getroot()
        for member in root.findall('object'):
            value = (root.find('filename').text,
                     int(root.find('size')[0].text),
                     int(root.find('size')[1].text),
                     member[0].text,
                     int(member[4][0].text),
                     int(member[4][1].text),
                     int(member[4][2].text),
                     int(member[4][3].text)
                     )
            xml_list.append(value)
    column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
    xml_df = pd.DataFrame(xml_list, columns=column_name)
    return xml_df

# 将 xml 资料转换成 train_labels.csv 与 test_labels.csv 两个档案
def main():
           image_path = os.path.join(os.getcwd(), 'totoro/images/train')
           xml_df = xml_to_csv(image_path)
           xml_df.to_csv('totoro/data/train_labels.csv', index=None)
           image_path = os.path.join(os.getcwd(), 'totoro/images/test')
           xml_df = xml_to_csv(image_path)
           xml_df.to_csv('totoro/data/test_labels.csv',index=None)
 
main()

第六步 : 制作 TensorFlow Record
%cd /root/models/totoro/tfrecord
!python generate_tfrecord.py --csv_input=/root/models/totoro/data/train_labels.csv \
  --output_path=train.record --image_dir=/root/models/totoro/images/train
!python generate_tfrecord.py --csv_input=/root/models/totoro/data/test_labels.csv\


--output_path=test.record --image_dir=/root/models/totoro/images/test

 

第七步 : 下载训练过的 MobileNet 模组

此步骤利用之前训练过的模组资源重新训练,即 迁移学习(Transfer Learning) 的技术。

%cd ~/models

import shutil

import tarfile

from requests import get

MODEL = 'ssd_mobilenet_v1_coco_2017_11_17'

MODEL_FILE = MODEL + '.tar.gz'

DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'

DEST_DIR = 'pretrained_model'

# 下载mobilenet 模组

if not (os.path.exists(MODEL_FILE)):

  with open(MODEL_FILE, "wb") as file:
    response = get(DOWNLOAD_BASE + MODEL_FILE)
    file.write(response.content)
 
# 解压缩 mobilenet 模组
tar = tarfile.open(MODEL_FILE)
tar.extractall()
tar.close()
os.remove(MODEL_FILE)
if (os.path.exists(DEST_DIR)):
  shutil.rmtree(DEST_DIR)
os.rename(MODEL, DEST_DIR)

# 移动 mobilenet.config" 资讯
shutil.move( "/root/models/research/object_detection/samples/configs/ssd_mobilenet_v1_coco.config",  "/root/models" )

第八步 : 修改 Config 档案
%cd /root/models/research/
# 编辑Pipeline 资讯
import tensorflow as tf
from google.protobuf import text_format
from object_detection.protos import pipeline_pb2
pipeline = pipeline_pb2.TrainEvalPipelineConfig()                                                       
config_path = '/root/models/ssd_mobilenet_v1_coco.config'
with tf.gfile.GFile( config_path, "r") as f:                                                                                           
    proto_str = f.read()                                                                                     
    text_format.Merge(proto_str, pipeline)
pipeline.train_input_reader.tf_record_input_reader.input_path[:] = ['/root/models/totoro/tfrecord/train.record'] # train data
pipeline.train_input_reader.label_map_path = '/root/models/totoro/data/object-detection.pbtxt'
pipeline.eval_input_reader[0].tf_record_input_reader.input_path[:] = ['/root/models/totoro/tfrecord/test.record'] # test data
pipeline.eval_input_reader[0].label_map_path = '/root/models/totoro/data/object-detection.pbtxt' # network
pipeline.train_config.fine_tune_checkpoint = '/root/models/pretrained_model/model.ckpt' # weight
pipeline.train_config.num_steps = 500 # training step
pipeline.model.ssd.num_classes = 2 # classes num
pipeline.eval_config.num_examples = 5 # test image number
config_text = text_format.MessageToString(pipeline)                                                        
with tf.gfile.Open( config_path, "wb") as f:                                                                                           
    f.write(config_text)

 

第九步 : 进行训练
!python /root/models/research/object_detection/legacy/train.py \
    --logtostderr \
    --train_dir=/root/models/trained \
    --pipeline_config_path=/root/models/ssd_mobilenet_v1_coco.config

*** 训练完成后,将于 models/trained/ 资料夹内产出 model.ckpt-500 档案

 

第十步 : 产生 Frozen Graph

此步骤可以调整模组输出大小,比如说将原本输入大小 224x224 改成 96x96 。

!python /root/models/research/object_detection/export_tflite_ssd_graph.py \
    --pipeline_config_path=/root/models/ssd_mobilenet_v1_coco.config \
    --output_directory=/root/models/fine_tuned_model \
    --trained_checkpoint_prefix=/root/models/trained/model.ckpt-500

*** 训练完成后,将于 models/fine_tuned_model / 资料夹内产出 tflite_graph.pb档案

第十一步 : TensorFlow Lite 转换
# 此处以指令方式进行转换,亦可使用上述文章所介绍代码方式。
! tflite_convert \
  --output_file=/root/models/fine_tuned_model/ mobilenetssd_uint8.tflite \
  --graph_def_file=/root/models/fine_tuned_model/tflite_graph.pb \
  --inference_type=QUANTIZED_UINT8 \
  --input_arrays=normalized_input_image_tensor \
  --input_shapes=1,300,300,3 \
  --output_arrays= 'TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3’ \
  --default_ranges_min=0 \
  --default_ranges_max=6 \
  --mean_values=128 \
  --std_dev_values=127 \
  --allow_custom_ops

*** 训练完成后,将于 models/fine_tuned_model / 资料夹内产出 mobilenetssd_uint8.tflite档案

第十二步 : Object Detection 范例实现 ( i.MX8M Plus 撰写运行)

import cv2
import numpy as np
from tflite_runtime.interpreter import Interpreter
# 解析 tensorflow lite 档案
interpreter = Interpreter(model_path='mobilenetssd_uint8.tflite') # 记得将模组移动至 i.MX8 平台
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
width = input_details[0]['shape'][2]
height = input_details[0]['shape'][1]
# 读取测试资料,并设置于解译器中
frame = cv2.imread('/root/models/totoro/images/test/image1.jpg')
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame_resized = cv2.resize(frame_rgb, (width, height))
input_data = np.expand_dims(frame_resized, axis=0)
interpreter.set_tensor(input_details[0]['index'], input_data)
# 进行推理
interpreter.invoke()
# 取得输出资料
detection_boxes = interpreter.get_tensor(output_details[0]['index']) # 输出位置资讯
detection_classes = interpreter.get_tensor(output_details[1]['index']) # 输出类别资讯
detection_scores = interpreter.get_tensor(output_details[2]['index']) # 输出分数资讯
num_boxes = interpreter.get_tensor(output_details[3]['index'])
# 标示物件
for i in range(10):
  if detection_scores[0, i] > .5: # 预测值大于 0.5则显示
    x = detection_boxes[0, i, [1, 3]] * frame_rgb.shape[1]
    y = detection_boxes[0, i, [0, 2]] * frame_rgb.shape[0]
    class_id = detection_classes[0, i]
    cv2.rectangle(frame_rgb, (x[0], y[0]), (x[1], y[1]), (0, 255, 0), 2)

cv2.imshow('TOTORO',frame_rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()

Object Detection 实现结果呈现

如下图所示,成功检测出豆豆龙(物件)。

在 i.MX8M Plus 的 NPU 处理器,推理时间(Inference Time) 约 9 ms

Object Detection 实现结果呈现 成功检测出豆豆龙(物件)。

 

四、结语

物件侦测是目前深度学习的一套基础应用,现在主流的算法架构多数为 YOLO 系列为主,并已发展到第七、八代的模组框架。而 MobileNet-SSD 的架构在准确度略输于 YOLO 架构,但仍是轻量化的速度表现上仍是一个标竿指标。在 i.MX8M Plus 的 NPU(Vivante VIP8000) 运行物件侦测应用,其推理时间可达每秒 8-9 ms 的处理速度,约 125 张 FPS 。此外,搭配本篇做法以及相应的资料库,就能训练出各式各样的物件侦测的应用,像是人脸侦测、手部侦测、水果侦测等等都是以这个概念。 下篇,将结合人脸资料库来实现所谓的 人脸侦测(Face Detection),敬请期待 !! 若对技术移植感兴趣的读者,可以持续关注 ATU 一部小编的系列博文 或是直接联系 ATU 团队 ! 谢谢 !!

五、参考文件

[1] SSD: Single Shot MultiBox Detector

[2] SSD-Tensorflow

[3] Single Shot MultiBox Detector (SSD) 论文阅读

[4] ssd-mobilenet v1 算法结构及程式码介绍

[5] Get models for TensorFlow Lite

[6] totoro example

如有任何相关 TensorFlow Lite 进阶技术问题,欢迎至博文底下留言提问 !!

接下来还会分享更多 TensorFlow Lite 进阶的技术文章 !!敬请期待 ATU Book-i.MX8系列 – TFLite 进阶】 !!

登录大大通,了解更多详情!

ATU Book-i.MX8系列 – TFLite 进阶

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1811564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flow Launcher:Windows高效启动与搜索工具

目录 一、软件简介 二、软件安装 三、软件功能介绍 3.1 快速启动应用 3.2 文件快速搜索 3.3 多功能操作中心 3.4 支持插件扩展 一、软件简介 Flow Launcher 是基于C#编程语言开发一款专为Windows设计的高效启动与搜索工具,它以创新简洁的界面重新定义了用户…

基于SWIFT和Qwen1.5-14B-Chat进行大模型LoRA微调测试

基于SWIFT和Qwen1.5-14B-Chat进行大模型LoRA微调测试 环境准备 基础环境 操作系统:Ubuntu 18.04.5 LTS (GNU/Linux 3.10.0-1127.el7.x86_64 x86_64)Anaconda3:Anaconda3-2023.03-1-Linux-x86_64根据服务器网络情况配置好conda源和pip源,此…

揭秘!义乌理阳是否涉足海外拼多多选品师项目?

在全球化的今天,跨境电商已成为一种趋势,越来越多的企业开始关注并投入这一领域。而拼多多作为国内知名的电商平台,其海外业务也在迅速扩展。那么,义乌理阳信息咨询服务有限公司是否有海外拼多多选品师的项目呢?下面我们将对此进…

JavaSE中的IO(输入/输出)字节流字符流

JavaSE中的IO(输入/输出)知识是一个广泛的领域,它涵盖了如何在Java程序中进行数据的读取和写入。以下是对JavaSE中IO知识的一个清晰归纳: 一、基础知识 流(Stream)的概念 流是一组有顺序的、有起点和终点…

大模型应用之基于 Langchain 的测试用例生成

一 用例生成实践效果 在组内的日常工作安排中,持续优化测试技术、提高测试效率始终是重点任务。近期,我们在探索实践使用大模型生成测试用例,期望能够借助其强大的自然语言处理能力,自动化地生成更全面和高质量的测试用例。 当前…

【通过新能源汽车的智慧数字底盘技术看计算机的相关技术堆栈?以后是软硬结合的全能程序员的天下,取代全栈(前后端都会的全栈程序员)】

汽车的“智慧数字底盘”是一个综合性的技术平台,旨在提升车辆的性能、安全性和驾驶体验。它集成了多种先进的技术和系统,是全能程序员的必杀技! 1. 传感器技术 a. 激光雷达(LiDAR) 用于生成高分辨率的3D地图&#…

PG sql调优案例学习

一,开发范式 1.不要轻易把字段嵌入到表达式 例:在sal列上有索引,但是条件语句中把sal列放在了表达式当中,导致索引被压抑,因为索引里面储存的是sal列的值,而不是sal加上100以后的值。 在条件中查询谁的工资1002000。这样写即使在sal上有索引也会走全表…

【倪诗韵神品连珠琴】音质纯净共鸣好,漆髹水墨黑云纹,讲究

【倪诗韵神品连珠琴】音质纯净共鸣好,漆髹水墨黑云纹,用料讲究。 此琴音质纯净共鸣好,非常清透,适合清风清新俊逸之流,琴体造型秀气,漆髹水墨黑云纹,用料讲究,木材纹理竖直而无疤。琴…

【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版7(附带项目源码)

最终效果 系列导航 文章目录 最终效果系列导航前言绘制进度条UI控制关卡进度测试按配置表使用关卡进度变化源码结束语 前言 本节主要实现关卡进度条的功能 绘制进度条UI 控制关卡进度测试 新增ProgressPanel代码,控制关卡进度 public class ProgressPanel : Mon…

kettle学习(利用jsonPath定位,json文件转换)

kettle学习(利用jsonPath定位,json文件转换) 于数据处理的广袤天地间,我们时常需应对各类繁杂状况与各式格式。Kettle 作为极具威力的数据集成利器,赋予了我们诸多功能与无限可能此次博客里,我们将重点投向…

一站到底-Vue移动端从零到一构建高效应用

​🌈个人主页:前端青山 🔥系列专栏:vue篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:一文精通Vue移动端:从零到一构建高效应用 目录 1、项目创建 2、引入组件库 二、功能实…

上位机图像处理和嵌入式模块部署(f407 mcu内部flash编程)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 对于f407这样的mcu来说,有的时候我们需要对mcu内部的flash进行编程处理。有两种情况需要对flash进行编程,一种情况是可能一…

深度学习500问——Chapter10:迁移学习(2)

文章目录 11.2 迁移学习的基本思路有哪些 11.2.1 基于样本迁移 11.2.2 基于特征迁移 11.2.3 基于模型迁移 11.2.4 基于关系迁移 11.2 迁移学习的基本思路有哪些 迁移学习的基本方法可以分为四种。这四种基本方法分别是:基于样本的迁移,基于模型的迁移&a…

电子元器件批发的几种模式

电子元器件的批发模式多种多样,以下是几种常见的模式: 传统批发模式:传统的电子元器件批发模式是指厂商或代理商通过与制造商签订合同,大批量购买元器件,并将其以较低的价格批发给零售商或其他中小型企业。这种模式通常…

树-二叉树的最大路径和

一、问题描述 二、解题思路 因为各个节点的值可能为负数,初始化res(最大路径和)的值为最小整数:Integer.MIN_VALUE 我们这里使用深度遍历(递归)的方法,先看某一个子树的情况: 这里有一个技巧,…

【C#】pdf按页分割文件,以及分页合并,效果还不错,你值得拥有

欢迎来到《小5讲堂》 这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解。 温馨提示:博主能力有限,理解水平有限,若有不对之处望指正! 目录 背景效果单页分割文件合并多页分割插件说明相关文章 背景 最近遇到一…

STM32Cube系列教程11:STM32 AES加解密模块性能测试

文章目录 本次测试环境本次测试所使用的系统时钟为48MHz本次测试主要测试对大量数据进行加解密所需的时间,本次为不严谨测试,忽略了程序调用耗时,结果仅供参考。 AES算法与数据加解密加密与解密对称加解密AES算法AES-ECBAES-CBC 填充算法PKCS…

ITIL简介重要组成部分

ITIL简介&重要组成部分 ITIL(Information Technology Infrastructure Library)是一个IT服务管理的最佳实践框架,通过服务战略、服务设计、服务过渡、服务运营和持续服务改进五个核心模块,帮助组织优化IT服务流程,…

嘴尚绝卤味:健康美味,引领卤味新风尚

在快节奏的现代生活中,人们对于美食的追求从未停歇。卤味作为中国传统美食的代表之一,以其独特的口感和丰富的营养,深受广大消费者的喜爱。而在众多卤味品牌中,嘴尚绝卤味凭借其健康、美味的特色,成为了市场上的佼佼者…

Pytorch解决 多元回归 问题的算法

Pytorch解决 多元回归 问题的算法 回归是一种基本的统计建模技术,用于建立因变量与一个或多个自变量之间的关系。 我们将使用 PyTorch(一种流行的深度学习框架)来开发和训练线性回归模型。 二元回归的简单示例 训练数据集(可获取&…