如何利用树莓派进行目标检测?这篇文章告诉你答案

这篇文章演示了如何使用树莓派来进行目标检测。考虑到深度学习和树莓派相机的的流行,我们认为如果能在树莓派上使用深度学习来检测任意的物体那就非常棒了。一旦你完成了模型的训练,你就可以把它下载到你的树莓派上了。使用树莓派进行预测的GitHub仓库(以检测新目标为例):

这个现实世界带来了许多挑战,例如数据有限、由于计算机硬件太小(如手机、Raspberry Pi)而无法运行复杂的深度学习模型等。本文演示了如何使用 Raspberry Pi 进行对象检测。就像路上的汽车、冰箱里的橘子、文件上的签名和太空中的特斯拉一样。

免责声明:我构建这个是为了帮助构建使用少量数据且没有计算机硬件的机器学习模型。

如果您迫切需要,请向下滚动到此帖子的底部以访问 Github 存储库。

为什么要进行物体检测?为什么选择 Raspberry Pi?

Raspberry Pi 是一款灵活的计算机硬件,已售出 1500 万台,俘获了一代消费者的心,黑客们也在其上构建了许多很酷的项目。考虑到深度学习和 Raspberry Pi 相机的流行,我们认为如果我们可以在 Raspberry Pi 上使用深度学习来检测任意物体,那就太好了。

现在,你可以在自拍照中检测到照片炸弹、有人进入 Harambe 的笼子、辣酱的位置或亚马逊送货员进入你的家。

如何利用树莓派进行目标检测?这篇文章告诉你答案

什么是物体检测?

2000 万年的进化让人类的视觉系统高度进化,人脑中 30% 的神经元负责处理视觉信息(而触觉和听觉分别只有 8% 和 3%)。相比机器,人类有两大优势,一是立体视觉,二是训练数据集的供应几乎是无限的(一个五岁的婴儿可以以大约 30fps 的采样间隔获得 2.7B 的图像数据)。

如何利用树莓派进行目标检测?这篇文章告诉你答案

为了模仿人类的表现,科学家将视觉感知任务分为四个不同的类别。

1.分类,为图像分配标签。

2.定位,为特定标签指定边框。

3. 物体检测,在图像中绘制多个边界框。

4.图像分割,获取图像中物体的精确位置区域。

对于许多应用来说,对象检测已经足够好了(图像分割是一种更准确的结果,但受到创建训练数据的复杂性的限制。人类注释者分割图像的时间通常比绘制边界框的时间长 12 倍。)此外,在检测到对象后,可以在边界框内单独分割该对象。

使用对象检测:

物体检测具有重要的实际意义,在各个行业得到了广泛的应用。以下是一些例子:

如何利用树莓派进行目标检测?这篇文章告诉你答案

我如何使用物体检测来解决我自己的问题?

物体检测可用于解决各种各样的问题。以下是一般分类:

1. 我的图像中是否存在物体?例如,我家里是否有入侵者?

2. 图像中的物体在哪里?例如,当汽车试图在世界各地导航时,了解物体的位置非常重要。

3. 图像中有多少个物体? 物体检测是统计物体数量的最有效方法之一,例如仓库货架上有多少个箱子。

4. 图片中有哪些不同类型的物体?例如,动物园的哪些区域有哪些动物?

5. 物体的尺寸是多少?尤其是使用静态相机,很容易计算物体的尺寸。例如,芒果的尺寸是多少?

6. 物体之间如何相互作用?例如,足球场上的阵型如何影响比赛结果?

7. 不同时间的物体位置(跟踪物体)?例如,跟踪火车之类的物体并计算其速度。

用 20 行代码完成物体检测

如何利用树莓派进行目标检测?这篇文章告诉你答案

YOLO 算法的可视化

物体检测的模型或结构有很多。每种模型或结构都在速度、大小和准确度之间进行权衡。我们选择了最受欢迎的一种:YOLO(你只看一次),并用 20 行代码(忽略注释)展示了它的工作原理。

注意:这是伪代码,而不是工作示例。它有一个非常标准的 CNN 黑匣子,如下所示:

您可以阅读有关(YOLO)的完整文章:

如何利用树莓派进行目标检测?这篇文章告诉你答案

YOLO中使用卷积神经网络的架构代码不到20行,如下:

#this is an Image of size 140x140. We will assume it to be black and white (ie only one channel, it would have been 140x140x3 for rgb)
image = readImage()
#We will break the Image into 7 coloumns and 7 rows and process each of the 49 different parts independently
NoOfCells = 7
#we will try and predict if an image is a dog, cat, cow or wolf. Therfore the number of classes is 4
NoOfClasses = 4
threshold = 0.7
#step will be the size of step to take when moving across the image. Since the image has 7 cells step will be 140/7 = 20
step = height(image)/NoOfCells
#stores the class for each of the 49 cells, each cell will have 4 values which correspond to the probability of a cell being 1 of the 4 classes
#prediction_class_array[i,j] is a vector of size 4 which would look like [0.5 #cat, 0.3 #dog, 0.1 #wolf, 0.2 #cow]
prediction_class_array = new_array(size(NoOfCells,NoOfCells,NoOfClasses))
#stores 2 bounding box suggestions for each of the 49 cells, each cell will have 2 bounding boxes, with each bounding box having x, y, w ,h and c predictions. (x,y) are the coordinates of the center of the box, (w,h) are it's height and width and c is it's confidence
predictions_bounding_box_array = new_array(size(NoOfCells,NoOfCells,NoOfCells,NoOfCells))
#it's a blank array in which we will add the final list of predictions
final_predictions = []
#minimum confidence level we require to make a prediction
threshold = 0.7
for (i<0; i<NoOfCells; i=i+1):
    for (j<0; j predictions_bounding_box_array[i,j,1, 4] else 1]
        # we will get the class which has the highest probability, for [0.5 #cat, 0.3 #dog, 0.1 #wolf, 0.2 #cow], 0.5 is the highest probability corresponding to cat which is at position 0. So index_of_max_value will return 0
        predicted_class = index_of_max_value(prediction_class_array[i,j])
        #we will check if the prediction is above a certain threshold (could be something like 0.7)
        if predictions_bounding_box_array[i,j,best_bounding_box, 4] * max_value(prediction_class_array[i,j]) > threshold:
            #the prediction is an array which has the x,y coordinate of the box, the height and the width
            prediction = [predictions_bounding_box_array[i,j,best_bounding_box, 0:4], predicted_class]
            final_predictions.append(prediction)
print final_predictions

如何建立物体检测的深度学习模型?

深度学习工作流程有6个基本步骤,分为三个部分:

1. 收集训练集

2.训练模型

3. 预测新图像

如何利用树莓派进行目标检测?这篇文章告诉你答案

第 1 阶段 — 收集训练数据

步骤 1. 收集图像(每个对象至少 100 张)

对于此任务,您可能需要收集每个对象的 100 张图像。尝试捕获与您用于做出决策的数据更相关的图像。

如何利用树莓派进行目标检测?这篇文章告诉你答案

步骤2.注释(在图像上手动绘制边界框)

在图像上绘制边界框。您可以使用 labelImg 之类的工具。通常需要人工为您注释图像。这是一项相当耗时的任务。

如何利用树莓派进行目标检测?这篇文章告诉你答案

第 2 阶段——在具有 GPU 的机器上训练模型第 3 步:找到用于迁移学习的预训练模型:

您可以在 /nanonets/nanonets-how-to-use-deep-learning-when-you-have-limited-data-f68c0b512cab 上阅读更多相关信息。为了减少训练所需的数据量,您需要一个预先训练的模型。如果没有它,您可能需要 100,000 多张图片来训练模型。

您可以在这里找到许多预先训练的模型。

步骤 4.在 GPU 上进行训练(像 AWS/GCP 这样的云服务或您自己的带有 GPU 的机器):

如何利用树莓派进行目标检测?这篇文章告诉你答案

Docker 镜像

训练模型的过程很难简化,我们创建了docker镜像以使模型更容易训练。

您可以通过运行以下代码开始训练模型:

sudo nvidia-docker run -p 8000:8000 -v `pwd`:data docker.nanonets.com/pi_training -m train -a ssd_mobilenet_v1_coco -e ssd_mobilenet_v1_coco_0 -p '{"batch_size":8,"learning_rate":0.003}'

有关如何使用的详细信息,请参阅此链接。

docker 镜像有一个 run.sh 脚本,可以使用以下参数调用:

run.sh [-m mode] [-a architecture] [-h help] [-e experiment_id] [-c checkpoint] [-p hyperparameters]
-h          display this help and exit
-m          mode: should be either `train` or `export`
-p          key value pairs of hyperparameters as json string
-e          experiment id. Used as path inside data folder to run current experiment
-c          applicable when mode is export, used to specify checkpoint to use for export

您可以在以下网站找到更详细的信息:

NanoNets/RaspberryPi-对象检测-TensorFlow

为了训练模型,您需要选择正确的超参数。

寻找正确的超参数

“深度学习”的艺术在于找出最佳参数,使模型最准确。这其中有一定的黑魔法,但也有一些理论。这是找到正确参数的绝佳资源。

量化模型(使其更小,以适合 Raspberry Pi 和手机等小型设备)

手机和 Raspberry Pi 等小型设备的内存和计算能力非常小。

训练神经网络是通过对权重进行许多小的调整来完成的,这项工作要求这些小的增量通常具有浮点精度(尽管也有努力使用量化模型表示)。

采用预先训练的模型和运行推理是非常不同的。深度神经网络的一大优点是它们往往更善于处理输入中的高噪声。

为什么要量化?

神经网络模型会占用大量磁盘空间;例如,原始 AlexNet 模型在浮点格式下超过 200MB。这个空间几乎完全由连接神经元的权重决定,因为一个简单的模型中通常有数百万个权重。

神经网络的节点和权重原本都是以 32 位浮点数存储的。量化模型最简单的方法是通过存储每层的最小值和最大值来压缩文件大小,然后将每个浮点数压缩为 8 位整数。这可以将文件大小减少 75%。

如何利用树莓派进行目标检测?这篇文章告诉你答案

量化模型的代码:

curl -L "https://storage.googleapis.com/download.tensorflow.org/models/inception_v3_2016_08_28_frozen.pb.tar.gz" |
  tar -C tensorflow/examples/label_image/data -xz
bazel build tensorflow/tools/graph_transforms:transform_graph
bazel-bin/tensorflow/tools/graph_transforms/transform_graph 
--in_graph=tensorflow/examples/label_image/data/inception_v3_2016_08_28_frozen.pb 
  --out_graph=/tmp/quantized_graph.pb 
  --inputs=input 
  --outputs=InceptionV3/Predictions/Reshape_1 
  --transforms='add_default_attributes strip_unused_nodes(type=float, shape="1,299,299,3")
    remove_nodes(op=Identity, op=CheckNumerics) fold_constants(ignore_errors=true)
    fold_batch_norms fold_old_batch_norms quantize_weights quantize_nodes
    strip_unused_nodes sort_by_execution_order

注意:我们的docker镜像内置了量化功能。第3阶段:使用Raspberry Pi对新图像进行预测第5步:用相机捕捉新图像

您需要打开并运行 Raspberry Pi 的相机,然后捕获新图像。

如何利用树莓派进行目标检测?这篇文章告诉你答案

有关如何安装的说明,请单击此处

import picamera, os
from PIL import Image, ImageDraw
camera = picamera.PiCamera()
camera.capture('image1.jpg')
os.system("xdg-open image1.jpg")

捕获新图像的代码

第 6 步:预测新图像下载模型

训练完模型后,您可以将其下载到 Raspberry Pi。要导入模型,请运行以下代码:

sudo nvidia-docker run -v `pwd`:data docker.nanonets.com/pi_training -m export -a ssd_mobilenet_v1_coco -e ssd_mobilenet_v1_coco_0 -c /data/0/model.ckpt-8998

接下来,将模型下载到Raspberry Pi。

在 Raspberry Pi 上安装 TensorFlow

根据您的设备,您可能需要更改一些安装说明。

sudo apt-get install libblas-dev liblapack-dev python-dev libatlas-base-dev gfortran python-setuptools libjpeg-dev
sudo pip install Pillow
sudo pip install http://ci.tensorflow.org/view/Nightly/job/nightly
git clone https://github.com/tensorflow/models.git
sudo apt-get install -y protobuf-compiler
cd models/research/
protoc object_detection/protos/*.proto --python_out=.
export PYTHONPATH=$PYTHONPATH:/home/pi/models/research:/home/pi/models/research/slim

运行模型预测新图像

python ObjectDetectionPredict.py --model data/0/quantized_graph.pb --labels data/label_map.pbtxt --images /data/image1.jpg /data/image2.jpg

Raspberry Pi 上的性能基准测试

Raspberry Pi 在内存和计算能力方面受到限制(与 Raspberry Pi GPU 兼容的 TensorFlow 版本仍然不可用),因此测量每个模型对新图像进行预测所需的时间非常重要。

如何利用树莓派进行目标检测?这篇文章告诉你答案

在 Raspberry Pi 上运行的不同对象检测模型的基准

使用 NanoNets 的工作流程:

如何利用树莓派进行目标检测?这篇文章告诉你答案

NanoNets 的目标之一是让我们的工作与深度学习轻松结合。对象检测是我们关注的一个领域,我们已经开发出一种工作流程来解决实施深度学习模型的一些挑战。

NanoNets 如何让这个过程变得更容易?

1. 无需评论

我们已经消除了注释图像的需要,我们有专业的注释者可以为您注释图像。

2.自动选择最佳模型和超参数

我们通过运行一系列具有不同参数的模型并为您的数据挑选最佳模型来自动为您训练最佳模型。

3. 无需昂贵的硬件和 GPU

NanoNets 完全在云端运行,不需要任何硬件。这使得它更容易使用。

4. 非常适合 Raspberry Pi 等移动设备

由于 Raspberry Pi 和手机等设备不适合运行复杂的计算任务,因此您可以将工作负载外包给我们的云,并为您完成所有计算。

以下是使用 NanoNets API 对图像进行预测的简单代码片段:

import picamera, json, requests, os, random
from time import sleep
from PIL import Image, ImageDraw
#capture an image
camera = picamera.PiCamera()
camera.capture('image1.jpg')
print('caputred image')
#make a prediction on the image
url = 'https://app.nanonets.com/api/v2/ObjectDetection/LabelFile/'
data = {'file': open('image1.jpg', 'rb'), 
    'modelId': ('', 'YOUR_MODEL_ID')}
response = requests.post(url, auth=requests.auth.HTTPBasicAuth('YOUR_API_KEY', ''), files=data)
print(response.text)
#draw boxes on the image
response = json.loads(response.text)
im = Image.open("image1.jpg")
draw = ImageDraw.Draw(im, mode="RGBA")
prediction = response["result"][0]["prediction"]
for i in prediction:
    draw.rectangle((i["xmin"],i["ymin"], i["xmax"],i["ymax"]), fill=(random.randint(1, 255),random.randint(1, 255),random.randint(1, 255),127))
im.save("image2.jpg")
os.system("xdg-open image2.jpg")

使用 NanoNets 进行图像预测的代码

构建你自己的 NanoNet

如何利用树莓派进行目标检测?这篇文章告诉你答案

你可以尝试建立自己的模型:

1. 使用 GUI(还可自动注释图像):

2.使用我们的API:

步骤 1:克隆此存储库

git clone 
cd object-detection-sample-python
sudo pip install requests

第 2 步:获取免费 API 密钥

在此获取免费 API 密钥

步骤 3:将 API 密钥设置为环境变量

export NANONETS_API_KEY=YOUR_API_KEY_GOES_HERE

步骤 4:创建新模型

python ./code/create-model.py

注意:在这里你将生成下一步需要的 MODEL_ID

步骤 5:将模型 ID 添加为环境变量

export NANONETS_MODEL_ID=YOUR_MODEL_ID

步骤 6:上传训练数据

收集您需要检测的物体的图像。您可以使用我们的网站 UI()

标记其中任何一个或使用开源工具(如 labelImg)。进入文件夹后。

准备数据、图像(图像文件)、注释(图像文件注释),并开始上传数据集。

python ./code/upload-training.py

步骤 7:训练模型

图像上传后,开始训练模型

python ./code/train-model.py

步骤 8:获取模型状态

该模型大约需要 2 小时进行训练。一旦模型开始训练,您将收到一封电子邮件并可以检查模型的状态。

watch -n 100 python ./code/model-state.py

第 9 步:做出预测

模型训练完成后,你可以使用它进行预测

python ./code/prediction.py PATH_TO_YOUR_IMAGE.jpg

代码(Github 存储库)

训练模型的 GitHub 存储库:

用于模型训练和量化的 Tensorflow 代码

用于模型训练的 NanoNets 代码

使用 Raspberry Pi 进行预测的 GitHub 仓库(以检测新目标为例):

用于在 Raspberry Pi 上进行预测的 Tensorflow 代码

用于在 Raspberry Pi 上进行预测的 NanoNets 代码

带注释的数据集:

印度道路上的汽车,从印度道路图像中提取车辆的数据集

通过

发起人:江凡利 校对:老赵 审阅:老赵

参与翻译(2人):小弟弟,狒狒

这是 6 年前发表的文章。请注意,其中的信息可能已发展或改变。

10,168

单片机

51 系列单片机中断源、堆栈特性及定时器/计数器详解

2024-6-10 22:10:29

单片机

工程信号与经典滤波器:二阶有源滤波器的典型结构分析

2024-6-10 23:09:47

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索