第 3 节:使用 TensorFlow 的计算机视觉的高级实现
在本节中,您将基于从上一节中获得的理解,并开发更新的概念并学习用于动作识别和对象检测的新技术。 在本节中,您将学习不同的 TensorFlow 工具,例如 TensorFlow Hub,TFRecord 和 TensorBoard。 您还将学习如何使用 TensorFlow 开发用于动作识别的机器学习模型。
在本节结束之前,您将能够执行以下操作:
本节包括以下章节:
动作识别是计算机视觉的关键部分,涉及识别人的手,腿,头和身体的位置,以检测特定的运动并将其分类为众所周知的类别。 困难在于视觉输入(例如,身体凌乱或衣服被覆盖)的变化,类似的动作,不同的类别(如饮用水或使用手持手机的通话)以及获得代表性的训练数据。
本章详细概述了可用于人体姿势估计和动作识别的关键方法。 动作识别将姿势估计方法与基于加速度的活动识别以及基于视频和三维点云的动作识别相结合。 该理论将通过使用 TensorFlow 2.0 的实现解释加以补充。
本章分为四个部分。 前三个讨论了可用于人体姿势估计的三种不同方法,而第四个全部涉及动作识别:
人体姿势估计是深度神经网络取得巨大成功的另一个领域,并且近年来发展迅速。 在最后几章中,我们了解到深度神经网络结合使用线性(卷积)和非线性(ReLU)运算来预测给定输入图像集的输出。 在姿势估计的情况下,当提供一组输入图像时,深度神经网络会预测关节位置。 图像中的标记数据集由一个边界框组成,该边界框确定图像中的N
个人和每人K
关节。 随着姿势的改变,关节的方向也会改变,因此通过观察关节的相对位置来表征不同的位置。 在以下各节中,我们将描述可以使用的不同姿势估计方法。
OpenPose 是第一个针对图像或视频中的多个人的开源实时二维姿态估计系统。 它主要由卡内基梅隆大学(CMU)的学生和教职员工开发。 论文的标题是《OpenPose:使用部分亲和力字段进行实时多人 2D 姿势估计》,作者是 Zhe Cao,Gines Hidalgo,Tomas Simon,Shih-En-Wei 和 Yaser Sheikh。 您可以在这个页面上找到该论文。
请注意,OpenPose 首次出现在 CVPR 2017 中,题目为《使用部分亲和力字段进行实时多人 2D 姿势估计》,可在这个页面中找到。 接下来是 2018 年的论文《OpenPose:使用部分亲和力字段的实时多人 2D 姿势估计》,网络得到了进一步改善。
本文的主要发现如下:
F
。 下图显示了 OpenPose 网络的架构:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hP22sIPK-1681784662627)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/2046a738-43a7-4f9b-9500-f98202f7a431.png)]
T[p]
编号预测部分相似性字段(PAF) 迭代次数,而第二阶段则以T[c]
迭代次数预测置信度图。 由于以下两个关键指标,2018 年提出的 OpenPose 模型是对 2017 年提出的早期模型的总体改进:3 x 3
卷积代替3 x 3
卷积。F
合并在一起,以为图像中的所有人产生二维关键点预测。 在估计的预测,地面真实特征映射和 PAF 之间的每个阶段的末尾都应用了损失函数。 重复此过程几次迭代,从而得到最新的特征映射和 PAF 检测。1 x 1
和1 x 1
核组成。 每个1 x 1
核的输出是连接的。在 2019 年,OpenPose 的作者以及其他一些人(Gines Hidalgo,Yaadhav Raaj,Haroon Idrees,Donglai Xiang,Hanbyul Joo,Tomas Simon1 和 Yaser Sheikh)提高了 OpenPose 的准确率和检测时间。 HTG0]单网络全身姿势估计。 您可以在这个页面上找到本文。
主要功能如下:
CMU 使用 OpenPose 模型,而 OpenCV 在其新的深度神经网络(DNN)框架中集成了经过预训练的 OpenPose 模型。 可以从下面的 GitHub 页面下载整个代码块。 该模型使用 TensorFlow 示例,而不是 OpenPose 作者最初使用的 Caffe 模型,可以在这个页面中找到。
可以使用以下命令在终端中执行 OpenCV 的 OpenPose 代码:
python openpose.py --input image.jpg
要开始使用 PC 的网络摄像头,只需在终端中键入以下内容:
python openpose.py
下图显示了针对足球运动员图像的 OpenPose 实现:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6mrHhLrx-1681784662628)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/512124c8-371f-4a6a-aa7f-d6197ff36961.png)]
该算法容易受到背景图像的影响,如以下棒球运动员的图像所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hji8c2vJ-1681784662628)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/d4e4d303-353f-46ae-94b9-6d6e1c91b18b.png)]
去除背景后,该算法的预测非常好。
让我们来看一下代码的主要功能。 我们将定义关键点,然后构建预测模型:
BODY_PARTS = { "Nose": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,"LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,"RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "REye": 14,"LEye": 15, "REar": 16, "LEar": 17, "Background": 18 }
POSE_PAIRS = [ ["Neck", "RShoulder"], ["Neck", "LShoulder"], ["RShoulder", "RElbow"],["RElbow", "RWrist"], ["LShoulder", "LElbow"], ["LElbow", "LWrist"],["Neck", "RHip"], ["RHip", "RKnee"], ["RKnee", "RAnkle"], ["Neck", "LHip"],["LHip", "LKnee"], ["LKnee", "LAnkle"], ["Neck", "Nose"], ["Nose", "REye"],["REye", "REar"], ["Nose", "LEye"], ["LEye", "LEar"] ]
net = cv.dnn.readNetFromTensorflow("graph_opt.pb")
使用tf-pose-estimation
在 TensorFlow 中实现 OpenPose。 TensorFlow/model/graph
的实际 GitHub 页面可在这个页面中找到。 请注意,可以在这个页面中找到 MobileNetV1 的描述。
cv.dnn.blobFromImage
对图像进行预处理(执行减法和缩放):net.setInput(cv.dnn.blobFromImage(frame, 1.0, (inWidth, inHeight), (127.5, 127.5, 127.5), swapRB=True, crop=False))
out = net.forward()
预测模型的输出,并获得 MobileNetV1 输出的前 19 个元素:out = out[:, :19, :, :] .
minMaxLoc
函数查找点值,并在其置信度高于阈值时添加点。 热图是用颜色表示的数据图:for i in range(len(BODY_PARTS)):
# Slice heatmap of corresponding body's part.
heatMap = out[0, i, :, :]
# Originally, we try to find all the local maximums. To simplify a sample
# we just find a global one. However only a single pose at the same time
# could be detected this way.
_, conf, _, point = cv.minMaxLoc(heatMap)
x = (frameWidth * point[0]) / out.shape[3]
y = (frameHeight * point[1]) / out.shape[2]
# Add a point if it's confidence is higher than threshold.
points.append((int(x), int(y)) if conf > args.thr else None)
cv.line
和cv.ellipse
显示关键点:for pair in POSE_PAIRS:
partFrom = pair[0]
partTo = pair[1]
assert(partFrom in BODY_PARTS)
assert(partTo in BODY_PARTS)
idFrom = BODY_PARTS[partFrom]
idTo = BODY_PARTS[partTo]
if points[idFrom] and points[idTo]:
cv.line(frame, points[idFrom], points[idTo], (0, 255, 0), 3)
cv.ellipse(frame, points[idFrom], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
cv.ellipse(frame, points[idTo], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
到目前为止,我们已经使用 OpenPose 通过自下而上的方法来确定多个身体姿势。 在下一节中,我们将使用堆叠的沙漏方法,该方法同时使用了自上而下和自下而上的方法。
栈式沙漏模型是由 Alejandro Newell,Kaiyu Yang 和 Jia Deng 于 2016 年在他们的论文“用于人体姿势估计的栈式沙漏网络”中开发的。 可以在这个页面中找到该模型的详细信息。
下图说明了该模型的架构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pzIXJtXB-1681784662629)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/7fc3ae51-e449-4258-864b-070ab283effc.png)]
该模型的主要功能如下:
1 x 1 Conv2D
,可将尺寸从 256 减少到 128 通道3 x 3 Conv2D
的 128 个通道1 x 1 Conv2D
,可将尺寸从 128 个通道增加到 256 个通道7 x 7
卷积开始,跨步为 2,将输入图像从7 x 7
带到64 x 64
,从而可以有效地使用 GPU 内存。2 x 2
合并用于对图像进行下采样。 在执行每个最大池化之前和之后,将残余块添加,然后在上采样到原始大小后再添加回主块。1 x 1 Conv2D
组成。2.5e-4
。 在 12 GB 的 NVIDIA Titan X GPU 上进行训练大约需要 3 天。沙漏模型在 MPII 人类姿态数据集中的所有关节上都达到了最先进的结果,但这是以占用资源密集型网络带宽为代价的。 这是由于每层通道数量众多而导致训练困难。 张峰,朱夏田和 Mao 在题为“快速人体姿态估计”的论文中,将 FastPose 蒸馏(FPD)引入 CVPR 2019。 与沙漏模型相比,FPD 可以实现更快,更经济的模型推断,同时达到相同的模型表现。 主要功能如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wosY1zwT-1681784662629)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/d44ab73e-308f-4e9b-915c-6c0299867377.png)]
在这里,K
是关节总数,L[pd]
是 FPD 的预测关节置信度图, m[ks]
是学生模型预测的第k
个关节的置信度图,而m[kt]
是教师模型预测的第k
个关节。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kUPHtwtJ-1681784662629)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/12c75f63-6358-4566-9007-1f3bcfbf9dec.png)]
此处, L[fpd]
是整体 FPD 损失函数,L[gt]
是用于真实情况标注的置信度图,而M
是权重函数。
可在这个页面中找到该模型的 Keras 实现。
请注意,下一部分的目的是详细解释沙漏网络的代码。 这是一个复杂的神经网络模型,其想法是,一旦掌握了这些代码,您就应该能够自己构建一个非常复杂的神经网络模型。 我们不会在前面的 GitHub 页面上详细说明如何运行代码。
在下一部分中,我们将描述模型的架构并进行详细说明。
下图显示了沙漏模型的编码块:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9CZrXazN-1681784662630)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/8e1b3ef1-f05d-4128-99fc-3d682e50f51c.png)]
让我们花一点时间来理解前面的图,因为我们将在以下部分中对其进行编码:
f1
,f2
,f4
和f8
,每个块分别具有 1、1/2、1/4 和 1/8 的分辨率。 如果查看架构图,就在堆叠的沙漏感应下,这应该很清楚。f1
,f2
,f4
和f8
–创建一个对应的特征映射,即lf1
,lf2
,lf4
和lf8
。lf1
,lf2
,lf4
和lf8
连接到右半块。 该块的输出为rf1
。lf8
特征映射。rf1
。 总共有两个头部快。 每个使用1 x 1
卷积。让我们看一下不同的代码块。
argparse
包Python 命令行参数(通过终端输入)允许程序通过parser.add_argument
命令获取有关神经网络操作的不同指令。 可以从argparse
函数包中导入。
下图显示了 16 种不同的类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uP4EvFCu-1681784662630)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/96a6b1d6-f6f7-4b80-8190-2f2d3a00c181.png)]
上图使用的代码块如下:
0 - r ankle, 1 - r knee, 2 - r hip, 3 - l hip, 4 - l knee, 5 - l ankle, 6 - pelvis, 7 - thorax, 8 - upper neck, 9 - head top, 10 - r wrist, 11 - r elbow, 12 - r shoulder, 13 - l shoulder, 14 - l elbow, 15 - l wrist
以下代码导入argparse
模块,TensorFlow 和 HourglassNet 模型。 它有两种类型的用户可选模型:用于小型网络的 128 个通道和用于大型网络的 256 个通道:
import argparse
import os
import tensorflow as tf
from keras import backend as k
from hourglass import HourglassNet
parser.add_argument("--resume", default=False, type=bool, help="resume training or not")
parser.add_argument("--resume_model", help="start point to retrain")
parser.add_argument("--resume_model_json", help="model json")
parser.add_argument("--init_epoch", type=int, help="epoch to resume")
parser.add_argument("--tiny", default=False, type=bool, help="tiny network for speed, inres=[192x128], channel=128")
args = parser.parse_args()
if args.tiny:
xnet = HourglassNet(num_classes=16, num_stacks=args.num_stack, num_channels=128, inres=(192, 192),outres=(48, 48))
else:
xnet = HourglassNet(num_classes=16, num_stacks=args.num_stack, num_channels=256, inres=(256, 256),outres=(64, 64))
if args.resume:
xnet.resume_train(batch_size=args.batch_size, model_json=args.resume_model_json,model_weights=args.resume_model,init_epoch=args.init_epoch, epochs=args.epochs)
else:
xnet.build_model(mobile=args.mobile, show=True)
xnet.train(epochs=args.epochs, model_path=args.model_path, batch_size=args.batch_size)
沙漏网络已被描述。 在本节中,我们将解释训练网络背后的代码。
如果您想训练自己的沙漏网络,请按照这个页面上的说明进行操作。
训练沙漏网络的代码如下:
def build_model(self, mobile=False, show=False):
if mobile:
self.model = create_hourglass_network(self.num_classes, self.num_stacks, self.num_channels, self.inres, self.outres, bottleneck_mobile)
else:
self.model = create_hourglass_network(self.num_classes, self.num_stacks,self.num_channels, self.inres, self.outres, bottleneck_block)
# show model summary and layer name
if show:
self.model.summary(def train(self, batch_size, model_path, epochs):
train_dataset = MPIIDataGen("../../data/mpii/mpii_annotations.json", "../../data/mpii/images"
inres=self.inres, outres=self.outres, is_train=True)
#here MPIIDataGen is a data generator function (not shown here) - it takes in json file and the images to preapre data for training similar to how we use image data generator in Chapter6.
train_gen = train_dataset.generator(batch_size, self.num_stacks, sigma=1, is_shuffle=True,rot_flag=True, scale_flag=True, flip_flag=True)
csvlogger = CSVLogger(os.path.join(model_path, "csv_train_" + str(datetime.datetime.now().strftime('%H:%M')) + ".csv"))
modelfile = os.path.join(model_path, 'weights_{epoch:02d}_{loss:.2f}.hdf5')
checkpoint = EvalCallBack(model_path, self.inres, self.outres)
xcallbacks = [csvlogger, checkpoint]
self.model.fit_generator(generatepochs=epochs, callbacks=xcallbacks)
前面的代码是如何设置神经网络进行训练的典型示例。 我们在“第 6 章”,“使用迁移学习的视觉搜索”中对此进行了详细介绍。 主要函数如下:
create_hourglass_network
是主要模型。train_dataset
使用 MPIIDatagen,这是用于输入数据的外部模块。train_gen
输入train_dataset
并放大图像。model.fit_generator
开始训练过程。沙漏模型代码的实际实现将在此处说明。 用于此的代码称为create_hourglass_network
。 如前所述,该代码具有以下组件。
以下代码描述了前端模块:
def create_front_module(input, num_channels, bottleneck):
_x = Conv2D(64, kernel_size=(7, 7), strides=(2, 2), padding='same', activation='relu', name='front_conv_1x1_x1')(input)
_x = BatchNormalization()(_x)
_x = bottleneck(_x, num_channels // 2, 'front_residual_x1')
_x = MaxPool2D(pool_size=(2, 2), strides=(2, 2))(_x)
_x = bottleneck(_x, num_channels // 2, 'front_residual_x2')
_x = bottleneck(_x, num_channels, 'front_residual_x3')
return _x
front_features = create_front_module(input, num_channels, bottleneck)
如前所述,它由一个 Conv2D 块组成,总共有 64 个过滤器,过滤器大小为7 x 7
,跨步为 2。该块的输出为(None, 32, 32,6)
。 接下来的几行贯穿批量规范化,瓶颈和最大池化层。 让我们定义瓶颈块。
左半块的代码如下:
def create_left_half_blocks(bottom, bottleneck, hglayer, num_channels):
# create left half blocks for hourglass module
# f1, f2, f4 , f8 : 1, 1/2, 1/4 1/8 resolution
hgname = 'hg' + str(hglayer)
f1 = bottleneck(bottom, num_channels, hgname + '_l1')
_x = MaxPool2D(pool_size=(2, 2), strides=(2, 2))(f1)
f2 = bottleneck(_x, num_channels, hgname + '_l2')
_x = MaxPool2D(pool_size=(2, 2), strides=(2, 2))(f2)
f4 = bottleneck(_x, num_channels, hgname + '_l4')
_x = MaxPool2D(pool_size=(2, 2), strides=(2, 2))(f4)
f8 = bottleneck(_x, num_channels, hgname + '_l8')
return (f1, f2, f4, f8)
前面的代码执行两个特定的操作:
1, ½, ¼, and 1/8
的过滤器系数(f1, f2, f4, and f8)
。接下来,下面的代码迭代从 0 到 2,以每个过滤器分辨率创建三个过滤器块:
for i in range(2):
head_next_stage, head_to_loss = create_left_half_blocks (front_features, num_classes, num_channels, bottleneck, i)
outputs.append(head_to_loss)
如果查看“编码沙漏模型部分开头的图像,您会注意到左右两个块由connect_left_to_right
块连接。 用于将左侧块连接到右侧块的代码如下:
def connect_left_to_right(left, right, bottleneck, name, num_channels):
'''
:param left: connect left feature to right feature
:param name: layer name
:return:
'''
_xleft = bottleneck(left, num_channels, name + '_connect')
_xright = UpSampling2D()(right)
add = Add()([_xleft, _xright])
out = bottleneck(add, num_channels, name + '_connect_conv')
return out
注意,每个右块是通过上采样生成的,并被添加到左块以生成最终输出。 在前面的代码中,_xleft
显示左侧块,_xright
显示右侧块,add
函数将两者相加。
右侧块的代码如下:
def create_right_half_blocks(leftfeatures, bottleneck, hglayer, num_channels):
lf1, lf2, lf4, lf8 = leftfeatures
rf8 = bottom_layer(lf8, bottleneck, hglayer, num_channels)
rf4 = connect_left_to_right(lf4, rf8, bottleneck, 'hg' + str(hglayer) + '_rf4', num_channels)
rf2 = connect_left_to_right(lf2, rf4, bottleneck, 'hg' + str(hglayer) + '_rf2', num_channels)
rf1 = connect_left_to_right(lf1, rf2, bottleneck, 'hg' + str(hglayer) + '_rf1', num_channels)
return rf1
在前面的代码中,lf8, lf4, lf2, and lf1
具有左特征。 相应的右图块的特征rf8, rf4, rf2, and rf1
是通过将左到右瓶颈图块应用到每个左图特征而生成的。 以下代码通过为每个左侧范围迭代 0 到 2 来应用此逻辑:
for i in range(2):
head_next_stage, head_to_loss = create_right_half_blocks (front_features, num_classes, num_channels, bottleneck, i)
outputs.append(head_to_loss)
头部快的代码如下:
def create_heads(prelayerfeatures, rf1, num_classes, hgid, num_channels):
# two head, one head to next stage, one head to intermediate features
head = Conv2D(num_channels, kernel_size=(1, 1), activation='relu', padding='same', name=str(hgid) + '_conv_1x1_x1')(rf1)
head = BatchNormalization()(head)
# for head as intermediate supervision, use 'linear' as activation.
head_parts = Conv2D(num_classes, kernel_size=(1, 1), activation='linear', padding='same',name=str(hgid) + '_conv_1x1_parts')(head)
# use linear activation
head = Conv2D(num_channels, kernel_size=(1, 1), activation='linear', padding='same',name=str(hgid) + '_conv_1x1_x2')(head)
head_m = Conv2D(num_channels, kernel_size=(1, 1), activation='linear', padding='same',name=str(hgid) + '_conv_1x1_x3')(head_parts)
head_next_stage = Add()([head, head_m, prelayerfeatures])
return head_next_stage, head_parts
头部有两个主要块,每个块由一个1 x 1 Conv2D
过滤器组成。 它使用激活层和填充。 作为复习,请参考“人体姿势估计-沙漏模型”部分下显示的沙漏架构图,以了解以下组件之间的联系:
以下逻辑将头部快应用于 0 到 2 的每个范围,分别对应于左块和右块:
for i in range(2):
head_next_stage, head_to_loss = create_head_blocks (front_features, num_classes, num_channels, bottleneck, i)
outputs.append(head_to_loss)
沙漏网络在 FLIC 人体姿势数据集上进行了训练,该数据集包含 5,000 张图像(用于训练的 4,000 和用于测试的 1,000)和具有 40,000 图片(用于训练的 28,000 和用于测试的 12,000)的 MPII 人体姿势数据集。
请注意,在本书中,我们没有使用 MPII 数据集来训练沙漏模型。 提供了有关 MPII 数据集的信息,以解释如何训练沙漏模型进行人体姿势估计。
在大约 20,000 次训练迭代中,所有关节的平均准确率达到大约 70%,最大准确率大约为 80%。
到目前为止,我们已经讨论了 OpenPose 和姿势估计的栈式沙漏方法。 在下一节中,我们将讨论 PoseNet。
TensorFlow 发布了 PoseNet 模型,该模型用于使用浏览器检测人体姿势。 它可以用于单个姿势和多个姿势。
PoseNet 基于 Google 的两篇论文。 一种使用自上而下的方法,而另一种使用自下而上的方法。
第一篇论文的标题为《在野外进行精确的多人姿势估计》,由 George Papandreou,Tyler Zhu,Nori Kanazawa,Alexander Toshev,Jonathan Tompson,Chris Bregler 和 Kevin Murphy 撰写。 您可以在这个页面上找到该论文。
这是一种由上而下的两阶段方法:
x, y, w, h
)。 在“第 5 章”,“神经网络架构和模型”中引入了更快的 R-CNN 和 ResNet,但在“第 10 章”,“使用 R-CNN,SSD 和 R-FCN 进行对象检测”中将在实际实现中一起使用它们。这种分类仅针对人类进行。 调整返回的所有边界框,使其具有固定的纵横比,然后将其裁剪为353 x 257
。3 x 17
输出替换最后一层。 已经使用分类和回归相结合的方法来找到人体的每个位置与 17 个关键点位置中的每个位置之间的偏移向量或距离。 每 17 个关键点计算一次距离小于半径的概率,从而得出 17 个热图。 使用 Sigmoid 激活函数训练具有 17 个热图的 ResNet-101 模型。第二篇论文的标题为《PersonLab:使用自下而上的,基于部分的几何嵌入模型的人员姿势估计和实例细分》,由第一篇论文的许多相同作者撰写; 分别是 George Papandreou,Tyler Zhu,Chen-Chieh Chen,Spyros Gidaris,Jonathan Tompson 和 Kevin Murphy。 您可以在这个页面上找到该论文。
在这种无框的,自下而上的方法中,作者使用卷积神经网络检测单个关键点及其相对位移,以将关键点分组为人的姿势实例。 另外,设计了几何嵌入描述符来确定人员分割。 该模型使用 ResNet-101 和 ResNet-152 架构进行训练。
像自顶向下方法一样,定义了一个 32 像素大小的半径,对应于 17 个关键点中的每一个。 然后,如果图像中的空间位置在关键点位置的半径之内,则以热图概率 1 定义 17 个独立的二元分类任务; 否则,将其设置为 0。与自顶向下方法一样,图像位置和关键点之间的距离也称为短距离偏移向量。 因此,存在 17 个这样的偏移向量。 与自顶向下方法一样,热图和偏移向量使用二维 Hough 得分图分组在一起。
在这种方法中,我们有一个与关键点相关联的人,但是当图像中存在多个人的实例时,这不允许我们对每个人的关键点进行分组。 为了解决这个问题,开发了 32 个独立的中距离二维偏移量字段来连接成对的关键点。 除此之外,还开发了一个由单个1 x 1 Conv2D
层组成的简单语义分割模型,该模型可以执行密集逻辑回归并计算每个图像像素至少属于一个人的概率。 语义分段的详细信息在“第 8 章”,《语义分段和神经样式迁移》中进行了描述。
有关预测图像的信息,请参阅以下有关自上而下与自下而上的文章和这个。 这两篇论文都包含大量示例图像。
预测关键点在两种方法之间或多或少是相同的,但是自上而下的方法从绘制边界框开始,而自下而上的方法执行语义分割。
到目前为止,我们已经讨论了 PoseNet 自上而下和自下而上方法背后的理论。 在本节中,我们将使用 PoseNet 识别这些操作。 有关如何实现 PoseNet 模型的详细信息,请参见这里。 查看此链接以了解 PoseNet 的文档。
接下来,我们将进行现场演示。 此实时演示是使用网络摄像头完成的,可以通过在网络浏览器中键入以下链接来启动。
尽管自上而下和自下而上的方法使用 ResNet-101 模型,但 PoseNet 模型使用 MobileNetV1 或 ResNet-50。 下表说明了它们之间的区别:
MobileNet V1 | ResNet 50 | |
---|---|---|
跨步 | 16 | 32 |
输入分辨率 | 宽度:640,高度:480 | 宽度:257,高度:200 |
PoseNet 网站说明了如何调整模型参数。 可以使用以下屏幕快照中显示的参数窗口来调整模型参数:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L6z3CCZF-1681784662630)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/c4ec18e5-b541-459f-a91d-ec8b5459fcb6.png)]
在前面的屏幕截图中,我们可以通过更改输入图像的分辨率来演示这两种模型,这似乎效果最好。
下图比较了八种不同配置(对于 MobileNetV1 和 ResNet,分辨率为 200 和 500 的上下姿势)的 PoseNet 输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LZTuUgXq-1681784662630)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/ad6e3682-bbcd-4f56-87f1-61b8ab1a23f4.png)]
上图显示,当人的手举起时,ResNet 平均比 MobileNetV1 更准确。 当手的位置向下时,表现大致相同。 同样,与 500 分辨率相比,200 分辨率可实现更好的关键点预测。 边界框选项可用,但未显示。 下图显示了用于其他配置的 ResNet 的边界框:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i3dTUlbt-1681784662631)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/53554316-613a-43bd-83ea-c0f0ee3ecbd6.png)]
请注意边界框的大小和位置在不同方向上如何变化。 关键点存储在向量中。 生成的关键点之间的角度可用于预测动作。 上一个图像由三个不同的动作组成–侧向运动,向上和向下运动。 这些动作的关键角度不会重叠,因此预测将是可靠的。
到目前为止,我们已经学习了如何在给定的关键点上进行训练以生成人体姿势。 手势识别的过程类似。 请按照以下步骤执行手势识别以进行手部运动:
Conv2D
层,一个最大合并层和一个 ReLU 层。
到目前为止,我们已经学习了如何开发用于训练的二维神经网络。 我们开发的网络也可以用于生产。
加速度计测量加速度的x
,y
和z
分量,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1P02cDxo-1681784662631)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/76b02856-dea6-432e-9557-50f717feeaf1.png)]
加速度计的这一特性使其可以放置在可穿戴设备中,例如安装在腕带上的手腕上的手机,智能手表,甚至是鞋子中,以测量加速度的 XYZ 分量。 在本节中,我们将学习如何使用神经网络分析加速度计数据以识别人类活动。 我们将使用 TensorFlow 开发机器学习模型。 这是本书中唯一讨论无图像的原始数据以及如何将其传递到神经网络以开发模型并从中进行推断的章节。
人类活动识别涉及基于加速度计数据对不同类型的活动进行分类。 这里的挑战是关联从不同类型的人体运动生成的加速度计数据,并基于不同的人体运动和活动来区分相似的加速度计轨迹。 例如,当左手移动和右手移动安装到人的腰部时,可能会产生类似的加速度计数据。 这减轻了加速度计数据应与姿势估计或视频图像数据结合的事实。 在本节中,我们将讨论可用于人类活动识别的两种不同工具。
此方法涉及以下步骤:
tf.data.Dataset
加载数据以开发简单,高效的数据管道。 tensor_slices
命令从输入中提取一片数据。flatten
和 Softmax 函数。请参阅以下 GitHub 页面上的代码,以获取遵循这些步骤的代码示例。
在上一个链接中可以找到两个文件:Chapter9_TF_Accelerometer_activity.ipynb
和sample.csv
。 下载两个文件,并将它们放在同一文件夹下。
sample.csv
文件是一个示例 CSV 文件,其中包含用于六个不同动作的加速度计(x, y, z)
数据:慢跑(0),步行(1),楼上(2),楼下(3) ,坐(4)和站立(5),每个动作都包含 5,000 个数据点。 在您的实际情况下,这些数据值可能会根据放置位置和所使用的加速度计的类型而有所不同。 最好使用相同的加速度计进行训练数据进行推理,以避免推理错误。
接下来,根据索引文件将数据分为两部分:训练和测试。 在这里,我们将评估两个不同的分割 18 和 28,这意味着在一种情况下,如果索引文件小于 18,则数据属于train
文件夹; 否则,它属于test
文件夹。 该模型加载了三个密集(全连接)的层,分辨率为 128。 最终的 softmax 层被 Sigmoid 函数代替。 下图显示了在三种不同情况下模型的迭代:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qjpzUFXY-1681784662631)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/434ae075-6174-4070-9006-4d9a692bf94c.png)]
前面的数据表明,每次迭代大约需要 40 秒,最终精度约为 0.97。 下图以图形方式说明了这一点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTQd854L-1681784662631)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/ba8fec99-a1e5-4e0e-adf3-5486104af508.png)]
前面的曲线表明,在所研究的三个条件下,训练的精度基本相同。 为了进一步分析这一点,让我们看一下下图中所示的置信度图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YrlaLSfn-1681784662632)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/0f9d22e3-ebfa-437f-92e4-11bc984fb1d0.png)]
混淆矩阵指示测试数据与预测数据的比较程度。 在这里,我们可以看到在索引 18 处进行了训练分割的 Softmax 函数比其他站立和步行案例提供了更好的结果。 不出所料,Softmax 与 Sigmoid 激活函数没有导致任何显着差异。 一旦开发了模型,就可以使用模型的预测函数来预测实际测试情况下的数据。
动作识别可以是二维的,也可以是三维的。 二维动作识别方法使用人体的关节信息,以关键点表示。 这些关键点以称为特征映射的向量表示。 另一方面,三维动作识别方法不仅需要特征映射,还需要全身的骨架数据。 可以使用深度传感器(例如 Microsoft Kinect 或 Intel RealSense)获得此数据。 在 2018 年,Diogo C.Luvizon,David Picard 和 Hedi Tabia 介绍了他们的论文 《使用多任务深度学习的 2D/3D 姿势估计和动作识别》。 可以在这里中找到本文的详细信息。
在本文中,作者在一个多任务框架中将基于高级人体关节的姿势信息与低级视觉特征(来自对象识别和特征识别)集成在一起。 该方法能够进行二维和三维动作识别。 使用体积表示将二维姿态图扩展为三维图。
这些技术的组合有助于使动作识别对类似身体的关节运动(如饮用水和打个电话)的抵抗力更强。
4D 动作识别意味着体积表示的三维动作是时间的函数。 可以将其视为对动作进行批量跟踪。 全全友和郝江提出了一种新颖的 4D 方法,名为《Action4D:人群和杂物中的在线动作识别》。可以在这个页面中找到本文的详细信息。
该方法使用 4D 表示跟踪人类,并在混乱和拥挤的环境中识别他们的行为。 本文的概念如下:
在本章中,我们了解并实现了三种不同的姿势估计方法-OpenPose,栈式沙漏和 PostNet。 我们学习了如何使用 OpenCV 和 TensorFlow 预测人类关键点。 然后,我们了解了栈式沙漏方法的详细理论和 TensorFlow 实现。 我们向您展示了如何在浏览器中评估人体姿势,以及如何使用网络摄像头实时估计关键点。 然后将人体姿势估计与动作识别模型链接,以演示如何使用两者来提高准确率。 基于加速的代码展示了如何使用 TensorFlow 2.0 加载数据,训练模型和预测动作。
在下一章中,我们将学习如何实现 R-CNN 并将其与其他 CNN 模型(如 ResNet,Inception 和 SSD)结合使用,以提高对象检测的预测,准确率和速度。
在“第 7 章”,“使用 YOLO 进行对象检测”中,我们了解了 YOLO 对象检测,然后在前两章中,我们了解了动作识别和图像修补。 本章通过为数据摄取和训练流水线以及模型开发奠定坚实的基础,标志着端到端(E2E)对象检测框架的开始。 在这里,我们将深入了解各种对象检测模型,例如 R-CNN,单发检测器(SSD),基于区域的全卷积网络(R-FCN)和 Mask R-CNN,并使用 Google Cloud 和 Google Colab 笔记本执行动手练习。 我们还将针对如何训练自己的自定义图像以使用 TensorFlow 对象检测 API 开发对象检测模型进行详细的练习。 我们将在本章结束时对各种对象跟踪方法进行深入概述,并使用 Google Colab 笔记本进行动手练习。
本章分为八个小节:
SSD 是一种非常快速的对象检测器,非常适合部署在移动设备和边缘设备上以进行实时预测。 在本章中,我们将学习如何使用 SSD 开发模型,在下一章中,我们将评估在边缘设备上部署时的表现。 但是在详细介绍 SSD 之前,我们将快速了解到目前为止我们在本书中了解的其他对象检测器模型。
我们在“第 5 章”,“神经网络架构和模型”中了解到,Faster R-CNN 包含 21,500 个区域提议(60 x 40
滑动窗口和 9 个锚定框),这些建议被扭曲为 2K 固定层。 这些 2K 层被馈送到全连接层和包围盒回归器,以检测图像中的包围盒。 9 个锚框来自 3 个比例尺,框面积分别为128^2
,256^2
,512^2
和三个长宽比:1:1、1:2 和 2:1。
9 个锚点框的说明如下:
128x128:1:1; 128x128:1:2; 128x128:2:1
256x256:1:1; 256x256:1:2; 256x256:2:1
512x512:1:1; 512x512:1:2; 512x512:2:1
在“第 7 章”,“使用 YOLO 进行对象检测”中,我们了解到 YOLO 使用单个 CNN,该 CNN 同时预测整个图像中对象的多个边界框。 YOLO v3 检测分为三层。 YOLO v3 使用 9 个锚点:(10, 13)
,(16, 30)
,(33, 23)
,(30, 61)
,(62, 45)
,(59, 119)
,(116, 90)
,(156, 198)
,(373, 326)
。 此外,YOLO v3 使用 9 个掩码,这些掩码链接到锚点,如下所述:
(116, 90)
,(156, 198)
,(373, 326)
(30, 61)
,(62, 45)
,(59, 119)
(10, 13)
,(16, 30)
,(33, 23)
SSD 于 2016 年由 Liu Wei,Dragomir Anguelov,Dumitru Erhan,Christian Szegedy,Scott Reed,傅成扬和 Alexander C.Berg 在题为《SSD:单发多框检测器》提出。
它的速度比 Faster R-CNN 快,但其准确率与 YOLO 相比。 改进来自消除区域提议并将小型卷积过滤器应用于特征映射,以预测不同比例的多层。
SSD 的主要功能概述如下:
conv4_3
,conv7
(fc7
),conv8_2
,conv9_2
,conv10_2
和conv11_2
组成,用于对象检测。c
类中每个类别的得分以及相对于地面真实情况的四个偏移,从而产生(c + 4)k
过滤器。 这些过滤器应用于特征映射(大小为m x n
),产生(c + 4)kmn
输出。 下表说明了这一点。 SSD 的独特之处在于默认框适用于不同分辨率的多个特征映射:层名称 | 检测 | 过滤器输出 |
---|---|---|
Conv4_3 | 38 x 38 x 4 = 5776 | 3 x 3 x 4 x (c + 4) |
Conv7 | 19 x 19 x 6 = 2166 | 3 x 3 x 6 x (c + 4) |
Conv8_2 | 10 x 10 x 6 = 600 | 3 x 3 x 6 x (c + 4) |
Conv9_2 | 5 x 5 x 6 = 150 | 3 x 3 x 6 x (c + 4) |
Conv10_2 | 3 x 3 x 4 = 36 | 3 x 3 x 4 x (c + 4) |
Conv11_2 | 4 | |
总 | 8732 |
smin(0.2)
到smax(0.95)
线性变化,而纵横比(ar
)可以取五个值(1
,2
,0.5
,3.0
和0.33
) ,其中k
在1
和m
之间变化。1
,添加了一个附加的默认框。 因此,每个特征映射位置最多有六个默认框。((i+0.5)/|fk|, (j+0.5)/|fk|)
,其中|fk|
是kth
正方形特征映射的大小,i
和j
的值从0
到|fk|
不等。 对六个默认框的每个重复此操作。human
和bus
组成并且都具有不同的宽高比和比例,则 SSD 显然可以识别两者。 问题出现在两个类别彼此接近且纵横比相同时,我们将在后面看到。0.5
的所有边界框。300x300
或512x512
图像大小,10^(-3)
的学习率为 40,000 次迭代,10^(-4)
至10^(-5)
的学习率为随后的 10,000 次迭代,衰减率为0.0005
和0.9
的势头。R-FCN 比 R-CNN 与 SSD 更相似。 R-FCN 由主要由 Microsoft Research 组成的团队于 2016 年开发,该团队由戴继峰,李毅,何凯明和孙健组成,题为《R-FCN:通过基于区域的全卷积网络进行对象检测》。 您可以在这个页面上找到该论文的链接。
R-FCN 也基于区域提议。 与 R-CNN 的主要区别在于,R-FCN 一直等到最后一层,然后应用选择性池提取特征以进行预测,而不是从 2K 区域提议网络开始。 在本章中,我们将使用 R-FCN 训练自定义模型,并将最终结果与其他模型进行比较。 下图描述了 R-FCN 的架构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zw2owfJf-1681784662632)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/d692d9d9-8340-4d58-a219-8002b8b93391.png)]
在上图中,汽车的图像通过 ResNet-101 生成了特征映射。 请注意,我们在“第 4 章”,“基于图像的深度学习”中使用,它介绍了如何可视化卷积神经网络(CNN)及其特征映射。 这种技术本质上是相同的。 然后,我们在特征映射内获取k x k
核(在此图像中,k = 3
),并将其在图像上滑动以创建k^2(C+1)
得分图。 如果得分图包含一个对象,则我们投票yes
,否则,我们投票no
。 展平不同区域之间的投票以创建 softmax 层,该层被映射到对象类别以进行检测。
R-FCN 的主要功能如下所述:
1×1
卷积层以进行维降。k^2
得分图,它对应于k^2(C + 1)
通道输出,带有C
对象类别加上背景。k^2
得分图中仅从得分图中提取响应。4k^2
卷积层上使用平均池,从而为每个关注区域层生成4k^2
维向量。 来自每个k^2
层的4k^2
向量被聚合为四维向量,该向量将边界框的位置和几何形状表征为x
,y
,宽度和高度 。0.0005
,动量为0.9
,将图像调整为高度为600
像素,20,000 批量的学习率为0.001
和0.0001
10,000 个批量。可以在这里找到 TensorFlow 对象检测 API。 在撰写本书时,TensorFlow 对象检测 API 仅适用于 TensorFlow 版本 1.x。 在终端中下载 TensorFlow 1.x 时,它将models/research/object detection
目录安装到您的 PC。 如果您的 PC 上装有 TensorFlow 2.0,则可以从 GitHub 下载研究目录。
TensorFlow 对象检测 API 具有预先训练的模型,您可以使用网络摄像头对其进行检测以及有关自定义图片的示例训练。 浏览前两个链接,然后自己尝试,然后返回下一部分。
在本章中,我们将使用 TensorFlow 对象检测器执行以下任务:
在所有这些示例中,我们将使用汉堡和薯条数据集进行检测和预测。
以下说明介绍了如何使用 Google Cloud 上的 TensorFlow 对象检测 API 来检测对象。 为此,您必须具有 Gmail 和 Google Cloud 帐户。 提交信用卡信息后,根据地区的不同,Google Cloud 可以在有限的时间内免费提供访问权限。 此免费访问权限应涵盖此处列出的练习。 请按照以下步骤在 Google Cloud Console 中创建虚拟机(VM)实例。 需要 VM 来运行 TensorFlow 对象检测 API 并进行推断:
R-CNN-trainingpack
是我的项目的名称。 您的项目名称可能会有所不同。
n1-standard-8
(8vCPU,30 GB 内存)。
staticip
),然后单击“保留”。
以下屏幕快照显示了在 Google 云平台中创建名为R-CNN-trainingpack
的项目:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zcwuFAkF-1681784662632)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/5a02623c-bc4c-4a7b-ab9c-1b9aca54f7f0.png)]
创建项目是第一步,然后我们将在项目中创建一个实例,如下面的屏幕快照所示。 此屏幕快照说明了我们刚刚描述的 VM 实例创建的步骤:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kvcUZ4Qp-1681784662632)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/84c13cc1-e50d-4291-b431-4a87579ab3d6.png)]
然后,按照以下说明在测试图像上创建对象检测推断:
username
,将密码设置为passw0rd
; 请记住,它不是o
而是0
,如零。正确遵循上述说明并上传图像后,您将获得如下所示的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-74VTutUF-1681784662633)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/9b7712b3-064e-4911-8ff3-7720963edf18.png)]
在此屏幕截图中,检测到了汉堡,酒杯和桌子,但未检测到炸薯条。 在下一节中,我们将看到为什么会这样,然后我们将训练自己的神经网络来检测这两者。
在此示例中,我们将从tfhub
导入 TensorFlow 库,并使用它来检测对象。 TensorFlow Hub 是一个库,其中的代码可用并且可以用于计算机视觉应用。 该代码是从 TensorFlow Hub 中提取的,但图像是在本地插入的,而不是云端。
可以在这个页面中找到用于此练习的修改后的代码。
在这里,我们通过导入tensorflow_hub
和six.moves
安装 TensorFlow 库。 six.moves
是一个 Python 模块,用于提供 Python 2 和 Python 3 之间的通用包。它显示图像并在图像上绘制边框。 在通过检测器之前,图像将转换为数组。 检测器是直接从集线器加载的模块,该模块在后台执行所有神经网络处理。 以下显示了在两种不同模型的tfhub
上运行示例图像时的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IzVFBOx8-1681784662633)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/1dfd202a-1189-4b8d-99d8-8ce5d20d32e9.png)]
如您所见,具有 Inception 和 ResNet 作为特征提取器的 R-CNN 可以正确预测汉堡包和炸薯条以及许多其他对象。 具有 MobileNet 模型的 SSD 可以检测到汉堡,但无法检测到薯条-将其分类为snacks
类别。 当我们训练自己的对象检测器并开发自己的模型并基于此进行推论时,我们将在下一部分中了解更多信息。
在本练习中,我们将使用 TensorFlow 对象检测 API 使用四种不同的模型训练自定义对象检测器。 Google Colab 是在 Google 服务器上运行的 VM,因此 TensorFlow 的所有包都得到了适当的维护和更新:
序号 | 模型 | 特征提取器 |
---|---|---|
1 | 更快的 R-CNN | Inception |
2 | SSD | MobileNet |
3 | SSD | Inception |
4 | R-FCN | ResNet-101 |
请注意,在撰写本书时,TensorFlow 对象检测 API 尚未迁移到 TensorFlow 2.x,因此请在 Google Colab 默认版本 TensorFlow 1.x 上运行此示例。 您可以通过键入%tensorflow_version 2.x
在 Google Colab 中安装 TensorFlow 2.x,但是对象检测 API 会导致错误。 该演示练习安装了 TenorFlow 1.14 版和 numpy 1.16 版。
我们将在此练习中使用迁移学习,首先从在 Coco 数据集上训练的预训练模型开始,然后在通过我们自己的数据集进行训练的基础上建立迁移学习。 TensorFlow 已经在 ModelZoo GitHub 站点中存储了预训练的模型,该站点可从这里获取。 这些模型主要是具有不同特征提取器的 R-CNN,SSD 和 R-FCN。 相应的配置文件可以在这个页面中找到。
可可数据集具有以下类别:
Person, bicycle, car, motorcycle, airplane, bus, train, truck, boat, traffic light, fire hydrant, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe, backpack, umbrella, handbag, tie, suitcase, frisbee, skis, snowboard, sports, ball, kite, baseball, bat, baseball, glove, skateboard, surfboard, tennis, racket, bottle, wine, glass, cup, fork, knife, spoon, bowl, banana, apple, sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, couch, potted plant, bed, dining table, toilet, tv, laptop, mouse, remote, keyboard, cell phone, microwave oven, toaster, sink, refrigerator, book, clock, vase, scissors, teddy bear, hair drier, toothbrush
如您所见,Coco 数据集没有burger
或French fries
作为类别。 形状接近这些的项目是sandwich
,donut
和carrot
。 因此,我们将获得模型权重,并在我们自己的数据集上使用迁移学习来开发检测器。 GitHub 网站上的 Jupyter 笔记本具有执行 E2E 训练工作的 Python 代码。
训练工作使用 TensorFlow 对象检测 API,该 API 在执行期间调用各种 Python .py
文件。 经过大量练习,我们发现,最好是使用 Google Colab 笔记本而不是您自己的 PC 来运行此工作。 这是因为许多库都是用 TensorFlow 1.x 版本编写的,需要进行转换才能在 TensorFlow 2.0 中工作。 此处显示了在本地 PC 上使用 Anaconda 运行作业时发生的一些错误示例:
module 'keras.backend' has no attribute 'image_dim_ordering'
self.dim_ordering = K.common.image_dim_ordering()
module 'tensorflow_core._api.v2.image' has no attribute 'resize_images'
rs = tf.image.resize(img[:, y:y+h, x:x+w, :], (self.pool_size, self.pool_size))
61 outputs.append(rs)
62
AttributeError: module 'tensorflow_core._api.v2.image' has no attribute 'resize_images'
当作业在 Colab 上的 TensorFlow 中运行时,模块之间的依存关系配置良好。 因此,不会花费很多时间解决许多简单的错误,您可以将时间花在训练开发上,而不是修正错误以开始训练。
在以下部分中,将提供逐步指南,以建立训练组合。 可以在这个页面中找到代码的详细信息。
.jpg
文件本节介绍如何处理图像,使其具有相同的格式和大小。 步骤在这里列出:
burger
和french fries
),则图像应包含大约三分之一的汉堡包,三分之一的薯条,以及三分之一两者的混合。 仅具有汉堡的图像和炸薯条的图像而不包含组合的图像是不好的。
.jpg
格式。
416x416
图像大小。 在 Linux 中,您可以使用 ImageMagick 批量调整图像大小。
file.jpg
-将其调整为416x416
图像尺寸file.jpg
。
classname_00x.jpg
格式。
例如,dec2f2eedda8e9.jpg
应该转换为burger_001.jpg
。 将所有图像保存在一个文件夹中。 由于我们的图像包含一个汉堡,炸薯条和一个组合,并且我们的文件总数为 100,因此对于图像文件名,请创建burger_001 …burger_030.jpg
,fries_031 …fries_060.jpg
和comb_061 …comb_100.jpg
三个类。
.xml
文件在本节中,我们将描述如何创建标注文件。 每个图像文件对应一个标注文件。 标注文件通常为.xml
格式。 此处描述了创建标注文件的步骤:
labelImg
创建标注文件。 此步骤已经在“第 7 章”,“使用 YOLO 的对象检测”中进行了讨论,但此处再次重复。 使用终端命令pip install labelImg
下载labelImg
。labelImg
即可打开。.jpg
文件)和目标(.xml
文件)目录。通常,人们会犯这样的错误:仅在一个类上绘制一个矩形,然后跳过另一个类。 这将导致在推理过程中仅检测到一个类别。
此屏幕快照显示了我们如何在一张图像中标记两个类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s03Lo1HH-1681784662633)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/850fcd9e-026d-4f49-b0bc-3497becfd97b.png)]
这显示了两个类别-burger
和fries
-以及如何使用labelImg
在它们周围绘制边框。 labelImg
的输出是.xml
文件,该文件存储在单独的文件夹中。
每个.xml
文件中都有相应的.jpg
文件。 因此,如果稍后手动更改labelImg
文件名,则文件系统将无法工作,您必须再次重新运行labelImg
。 同样,如果在labelImg
操作之后调整图像大小,则标注文件的位置将更改,并且您将必须重新运行labelImg
。
在本节中,我们将数据集分为train
和test
文件夹。 这是必需的,因为train
模型使用train
数据集生成模型,并使用test
数据集进行验证。 请注意,有时test
和val
名称可以互换使用来表示同一事物。 但是总的来说,我们需要第三个文件夹来检查最终模型是否与该模型以前未见过的一些未知图像相对应。 包含这些图像的文件夹称为val
-稍后将进行讨论。
请按照此处列出的步骤将图像分成train
和test
文件夹。 请注意,这些任务将在 Google Colab 上完成:
train
和test
。.jpg
和.xml
文件复制到任何文件夹中。 因此,现在该文件夹将包含背对背.jpg
和.xml
文件。.jpg
和相应的.xml
文件)复制到train
文件夹中。 因此,完成本练习后,train
文件夹中将有大约 140 个文件(70 个.jpg
文件和 70 个.xml
文件)。test
文件夹中。train
和test
文件夹都上传到data
下的 Google 云端硬盘。val
的验证文件夹,并将所有类中的一些图像插入其中。请注意,在此示例中,在train
和test
文件夹之间使用了 70/30 的比例,但是通常,数字范围可以从 90/10 到 70/30。
Chapter10_R-CNN
的文件夹,然后在其中创建一个名为data
的文件夹:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xi5RFMcy-1681784662633)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/81b9b12b-0335-4dab-9b85-eeb146b53bf1.png)]
data
文件夹后,在 Google 云端硬盘中在其中创建两个名为annotations
和images
的新文件夹,如图所示。 下一个任务是填充这些目录。此屏幕快照显示了Chapter10_R-CNN
中的目录结构和命名约定:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mbunY6S9-1681784662634)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/59e995d5-155b-49ca-8e54-76b27fe1e60e.png)]
如上图所示的目录结构应在 Google 云端硬盘中建立。 请按照此处描述的格式开始使用:
images
文件夹,需要提供所有图像数据。 请记住要遵循前面的图中概述的命名约定,并将.jpg
文件和.xml
文件上传到相应的目录,如上图所示。由于大小限制,我们无法将图像数据上传到 GitHub 站点。 因此,本部分中使用的图像可以从这里的 Kaggle 食品图像(用于汉堡和薯条样本)下载。 电话并上传。
annotations
是输出文件夹,应为空,并将在下一部分中填写。 不要将annotations
文件夹与标注图像混淆以创建.xml
文件。 所有.xml
文件都放在images
文件夹中。现在我们的图像准备工作已经完成,我们将开始在 Google Colab 笔记本中进行编码。 第一步是参数配置和获取训练工作所需的包,这涉及模型的类型,训练参数等等。 请按照以下步骤执行此操作:
Chapter10_Tensorflow-Training_a_Object_Detector_GoogleColab.ipynb
Python 文件保存到 Google 云端硬盘,然后将其作为 Colab 笔记本打开。Configure
参数,然后通过按Shift + Enter
安装所需的包。config
参数创建测试模型,这是开始构建数据并准备进行测试之前的先决条件:Running tests under Python 3.6.9: /usr/bin/python3
[ RUN ] ModelBuilderTest.test_create_experimental_model
[ OK ] ModelBuilderTest.test_create_experimental_model
[ RUN ] ModelBuilderTest.test_create_faster_R-CNN_model_from_config_with_example_miner
[ OK ] ModelBuilderTest.test_create_faster_R-CNN_model_from_config_with_example_miner
[ RUN ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_faster_R-CNN_with_matmul
[ OK ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_faster_R-CNN_with_matmul
[ RUN ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_faster_R-CNN_without_matmul
[ OK ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_faster_R-CNN_without_matmul
[ RUN ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_mask_R-CNN_with_matmul
[ OK ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_mask_R-CNN_with_matmul
[ RUN ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_mask_R-CNN_without_matmul
[ OK ] ModelBuilderTest.test_create_faster_R-CNN_models_from_config_mask_R-CNN_without_matmul
[ RUN ] ModelBuilderTest.test_create_rfcn_model_from_config
[ OK ] ModelBuilderTest.test_create_rfcn_model_from_config
[ RUN ] ModelBuilderTest.test_create_ssd_fpn_model_from_config
[ OK ] ModelBuilderTest.test_create_ssd_fpn_model_from_config
[ RUN ] ModelBuilderTest.test_create_ssd_models_from_config
[ OK ] ModelBuilderTest.test_create_ssd_models_from_config
[ RUN ] ModelBuilderTest.test_invalid_faster_R-CNN_batchnorm_update
[ OK ] ModelBuilderTest.test_invalid_faster_R-CNN_batchnorm_update
[ RUN ] ModelBuilderTest.test_invalid_first_stage_nms_iou_threshold
[ OK ] ModelBuilderTest.test_invalid_first_stage_nms_iou_threshold
[ RUN ] ModelBuilderTest.test_invalid_model_config_proto
[ OK ] ModelBuilderTest.test_invalid_model_config_proto
[ RUN ] ModelBuilderTest.test_invalid_second_stage_batch_size
[ OK ] ModelBuilderTest.test_invalid_second_stage_batch_size
[ RUN ] ModelBuilderTest.test_session
[ SKIPPED ] ModelBuilderTest.test_session
[ RUN ] ModelBuilderTest.test_unknown_faster_R-CNN_feature_extractor
[ OK ] ModelBuilderTest.test_unknown_faster_R-CNN_feature_extractor
[ RUN ] ModelBuilderTest.test_unknown_meta_architecture
[ OK ] ModelBuilderTest.test_unknown_meta_architecture
[ RUN ] ModelBuilderTest.test_unknown_ssd_feature_extractor
[ OK ] ModelBuilderTest.test_unknown_ssd_feature_extractor
----------------------------------------------------------------------
Ran 17 tests in 0.157s
OK (skipped=1)
这是非常重要的一步,我们许多人为此奋斗。 请按照以下步骤创建您的tfRecord
文件。 您必须在上一步中安装所有必需的包,然后才能继续执行此步骤:
Chapter10_R-CNN
文件夹下,data
下有两个文件名为xml_to_csv.py
并生成tfrecord.py
。 这些文件应从本地驱动器复制到 Google 云端硬盘。pip install TensorFlow
或pip install tensorflow-gpu
安装 TensorFlow 时,它将在home
目录下创建一个models-master
目录。 在其中,导航到research
文件夹,然后导航到object_detection
文件夹,您将找到xml_to_csv.py
并生成tfrecord.py
。 如前所述,将它们复制并插入 Google 云端硬盘。 您还可以在本地运行以下步骤,但是使用 TensorFlow 2.0 在本地运行时,我注意到错误,因此对于本练习,我们将在 Google Colab 中运行它。Chapter10_R-CNN
文件夹链接到您的 Colab 笔记本。 这是通过使用以下命令完成的:from google.colab import drive
drive.mount('/content/drive')
Chapter10_R-CNN
目录:%cd /content/drive/My Drive/Chapter10_R-CNN
tfRecord
文件。.xml
文件从train
数据转换为data/annotations
文件夹中的train_labels.csv
文件:!python xml_to_csv.py -i data/images/train -o data/annotations/train_labels.csv -l data/annotations
.xml
文件从test
数据转换为data/annotations
文件夹中的test_labels.csv
文件:!python xml_to_csv.py -i data/images/test -o data/annotations/test_labels.csv
train_labels.csv
生成train.record
文件,从train
文件夹生成图像jpg
文件。 它还会生成lable_map.pbtxt
文件:!python generate_tfrecord.py --csv_input=data/annotations/train_labels.csv --output_path=data/annotations/train.record --img_path=data/images/train --label_map data/annotations/label_map.pbtxt
test_labels.csv
生成test.record
文件,从test
文件夹生成图像jpg
文件。 它还会生成lable_map.pbtxt
文件:!python generate_tfrecord.py --csv_input=data/annotations/test_labels.csv --output_path=data/annotations/test.record --img_path=data/images/test --label_map data/annotations/label_map.pbtx
tfRecord
文件。 请注意,扩展名可以是tfRecord
或record
:/content/drive/My Drive/Chapter10_R-CNN
Successfully converted xml to csv.
Generate `data/annotations/label_map.pbtxt`
Successfully converted xml to csv.
WARNING:tensorflow:From generate_tfrecord.py:134: The name tf.app.run is deprecated. Please use tf.compat.v1.app.run instead.
WARNING:tensorflow:From generate_tfrecord.py:107: The name tf.python_io.TFRecordWriter is deprecated. Please use tf.io.TFRecordWriter instead.
W0104 13:36:52.637130 139700938962816 module_wrapper.py:139] From generate_tfrecord.py:107: The name tf.python_io.TFRecordWriter is deprecated. Please use tf.io.TFRecordWriter instead.
WARNING:tensorflow:From /content/models/research/object_detection/utils/label_map_util.py:138: The name tf.gfile.GFile is deprecated. Please use tf.io.gfile.GFile instead.
W0104 13:36:52.647315 139700938962816 module_wrapper.py:139] From /content/models/research/object_detection/utils/label_map_util.py:138: The name tf.gfile.GFile is deprecated. Please use tf.io.gfile.GFile instead.
Successfully created the TFRecords: /content/drive/My Drive/Chapter10_R-CNN/data/annotations/train.record
WARNING:tensorflow:From generate_tfrecord.py:134: The name tf.app.run is deprecated. Please use tf.compat.v1.app.run instead.
WARNING:tensorflow:From generate_tfrecord.py:107: The name tf.python_io.TFRecordWriter is deprecated. Please use tf.io.TFRecordWriter instead.
W0104 13:36:55.923784 140224824006528 module_wrapper.py:139] From generate_tfrecord.py:107: The name tf.python_io.TFRecordWriter is deprecated. Please use tf.io.TFRecordWriter instead.
WARNING:tensorflow:From /content/models/research/object_detection/utils/label_map_util.py:138: The name tf.gfile.GFile is deprecated. Please use tf.io.gfile.GFile instead.
W0104 13:36:55.933046 140224824006528 module_wrapper.py:139] From /content/models/research/object_detection/utils/label_map_util.py:138: The name tf.gfile.GFile is deprecated. Please use tf.io.gfile.GFile instead.
Successfully created the TFRecords: /content/drive/My Drive/Chapter10_R-CNN/data/annotations/test.reco
接下来,使用以下命令下载并解压缩基本模型。 在“配置参数和安装所需包”部分的配置参数步骤中,已选择模型和相应的配置参数。 可以根据配置参数和批量大小选择四种不同的模型(SSD,Faster R-CNN 和 R-FCN 的两种变体)。 您可以从指示的批量大小开始,并在模型优化期间根据需要进行调整:
MODEL_FILE = MODEL + '.tar.gz'
DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'
DEST_DIR = '/content/models/research/pretrained_model'
在这里,目标目录是 Google Colab 笔记本本身,content/models/research
目录就在其中-因此,无需自己创建一个目录。 当您安装所需的包部分时,便完成了此操作。
此步骤还将从您的label_map.pbtxt
文件中自动下载许多类,并调整大小,比例,长宽比和卷积超参数,以准备进行训练。
TensorBoard 是用于实时监控和可视化训练进度的工具。 它可以绘制训练损失和准确率的图表,因此无需手动绘制。 TensorBoard 允许您可视化模型图并具有许多其他功能。 访问这里,以了解有关 TensorBoard 功能的更多信息。
通过添加以下代码行,可以将 TensorBoard 添加到模型训练中。 检查 GitHub 页面上提供的代码以获取确切位置:
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
history = model.fit(x=x_train, y=y_train, epochs=25, validation_data=(x_test, y_test), callbacks=[tensorboard_callback])
然后,可以在训练开始后通过在终端中键入以下内容来可视化 TensorBoard 图:
%tensorboard --logdir logs/fit
本节介绍如何在 Google Colab 上运行 TensorBoard。 这涉及以下步骤:
!wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
!unzip ngrok-stable-linux-amd64.zip
LOG_DIR = model_dir
get_ipython().system_raw(
'tensorboard --logdir {} --host 0.0.0.0 --port 6006 &
.format(LOG_DIR))
ngrok
以使用端口6006
启动 TensorBoard,该端口是用于通信和交换数据的迁移通信协议:get_ipython().system_raw('./ngrok http 6006 &')
! curl -s http://localhost:4040/api/tunnels | python3 -c \
"import sys, json; print(json.load(sys.stdin)['tunnels'][0]['public_url'])"
完成上述所有步骤后,我们已准备好进行最重要的步骤-训练自定义神经网络。
训练模型是通过以下五个步骤执行的,这些步骤也在代码中概述:
STDERR
文件的位置。!python /content/models/research/object_detection/model_main.py \
--pipeline_config_path={pipeline_fname} \
--model_dir={model_dir} \
--alsologtostderr \
--num_train_steps={num_steps} \
--num_eval_steps={num_eval_steps}
此代码的说明如下:
pipeline_fname
定义,这是模型和配置文件。Model_dir
是training
目录。 注意TensorBoard LOG_DIR
也映射到model_dir
,因此 TensorBoard 在训练期间获取数据。训练成功开始后,您将开始在 Jupyter 笔记本中查看消息。 在某些包上的某些警告被弃用之后,您将开始看到有关训练步骤的注解并成功打开了动态库:
INFO:tensorflow:Maybe overwriting train_steps: 1000
Successfully opened dynamic library libcudnn.so.7
Successfully opened dynamic library libcublas.so.10
INFO:tensorflow:loss = 2.5942094, step = 0
loss = 2.5942094, step = 0
INFO:tensorflow:global_step/sec: 0.722117
global_step/sec: 0.722117
INFO:tensorflow:loss = 0.4186823, step = 100 (138.482 sec)
loss = 0.4186823, step = 100 (138.482 sec)
INFO:tensorflow:global_step/sec: 0.734027
global_step/sec: 0.734027
INFO:tensorflow:loss = 0.3267398, step = 200 (136.235 sec)
loss = 0.3267398, step = 200 (136.235 sec)
INFO:tensorflow:global_step/sec: 0.721528
global_step/sec: 0.721528
INFO:tensorflow:loss = 0.21641359, step = 300 (138.595 sec)
loss = 0.21641359, step = 300 (138.595 sec)
INFO:tensorflow:global_step/sec: 0.723918
global_step/sec: 0.723918
INFO:tensorflow:loss = 0.16113645, step = 400 (138.137 sec)
loss = 0.16113645, step = 400 (138.137 sec)
INFO:tensorflow:Saving checkpoints for 419 into training/model.ckpt.
model.ckpt-419
INFO:tensorflow:global_step/sec: 0.618595
global_step/sec: 0.618595
INFO:tensorflow:loss = 0.07212131, step = 500 (161.657 sec)
loss = 0.07212131, step = 500 (161.657 sec)
INFO:tensorflow:global_step/sec: 0.722247
] global_step/sec: 0.722247
INFO:tensorflow:loss = 0.11067433, step = 600 (138.457 sec)
loss = 0.11067433, step = 600 (138.457 sec)
INFO:tensorflow:global_step/sec: 0.72064
global_step/sec: 0.72064
INFO:tensorflow:loss = 0.07734648, step = 700 (138.765 sec)
loss = 0.07734648, step = 700 (138.765 sec)
INFO:tensorflow:global_step/sec: 0.722494
global_step/sec: 0.722494
INFO:tensorflow:loss = 0.088129714, step = 800 (138.410 sec)
loss = 0.088129714, step = 800 (138.410 sec)
INFO:tensorflow:Saving checkpoints for 836 into training/model.ckpt.
I0107 15:44:16.116585 14036592158
INFO:tensorflow:global_step/sec: 0.630514
global_step/sec: 0.630514
INFO:tensorflow:loss = 0.08999817, step = 900 (158.601 sec)
loss = 0.08999817, step = 900 (158.601 sec)
INFO:tensorflow:Saving checkpoints for 1000 into training/model.ckpt.
Saving checkpoints for 1000 into training/model.ckpt.
INFO:tensorflow:Skip the current checkpoint eval due to throttle secs (600 secs).
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.505
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.915
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.493
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = -1.000
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.200
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.509
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.552
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.602
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.611
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = -1.000
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.600
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.611
SavedModel written to: training/export/Servo/temp-b'1578412123'/saved_model.pb
INFO:tensorflow:Loss for final step: 0.06650969.
Loss for final step: 0.06650969.
请注意前面显示的输出。 根据您的 CPU/GPU 功能,执行此步骤将花费不同的时间。 在前面的训练输出中要注意的最重要的事情是训练期间的准确率和召回率值。
此步骤涉及导出训练有素的推理图并运行推理测试。 推断是使用以下 Python 命令完成的:
!python /content/models/research/object_detection/export_inference_graph.py \
--input_type=image_tensor \
--pipeline_config_path={pipeline_fname} \
--output_directory={output_directory} \
--trained_checkpoint_prefix={last_model_path}
此处,last_model_path
是model_dir
,其中在训练期间存储模型检查点,而pipeline_fname
是模型路径和配置文件。 检查点涵盖训练过程中模型使用的参数值。 下图显示了训练期间开发的四种不同模型的输出。 通过执行上述步骤并仅选择不同的模型类型,它们可以逐一运行:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6cvH4PD5-1681784662634)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/e37adfb1-d76d-4334-bd0c-a4449b18bf33.png)]
请注意,前面提到的带有代码块的模型针对四种不同的模型运行。 在运行下一个模型之前,请单击 Google Colab 页面顶部的“运行时”,然后选择“工厂重置运行时”,以便为新模型重新开始。 请注意,SSD 模型仍然无法正确检测对象,而 R-CNN 和 R-FCN 则可以正确检测汉堡和薯条。 这可能是由于汉堡和薯条的大小几乎相同,并且我们从 SSD 概述中了解到 SSD 可以更好地检测不同比例的图像。
设置 TensorBoard 后,可以在 TensorBoard 中可视化输出。
TensorBoard 具有三个选项卡-标量,图像和图。 标量包括 mAP(精度),召回率和损失值,图像包括先前的视觉图像,图包括 TensorFlow 图frozen_inference_graph.pb
文件。 请注意,精度和召回率之间的差异定义如下:
精度 = 真正 / (真正 + 假正)
召回 = 真正 / (真正 + 假负)
请注意,我们仅使用 68 张图像来训练我们的神经网络,它给了我们很好的预测。 这提出了四个问题:
burger
和fries
两类,因此它可以检测其他与汉堡形状类似的对象,例如甜甜圈。 要解决此问题,我们需要加载类似于burger
的图像并将其分类为非burger
,然后使用这些其他图像集训练模型。cheeseburger
作为一类,因此对少于 100 张图像的迁移学习效果很好。Mask R-CNN 由 Kaiming He,Georgia Gkioxari,Piotr Dollar 和 Ross Girshick 在 CVPR 2017 中提出。Mask R-CNN 使用 R-CNN 有效地检测图像中的对象,同时针对每个兴趣区域进行对象分割任务。 因此,分割任务与分类和边界框回归并行工作。 Mask R-CNN 的高级架构如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5SLMxjXQ-1681784662639)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/2884d889-f0b0-44e5-83cf-22ec8797f59a.png)]
Mask R-CNN 实现的详细信息如下:
M x N
)掩码。M x N
网格后,将 RoI Align 应用于区域提议网络的输出,然后在每个箱子中应用2 x 2
箱子和四个采样点 ,使用双线性插值选择。 RoI Align 用于将提取的特征与输入对齐。0.02
高达 120,000 次迭代,然后下降到0.002
。 使用0.0001
的权重衰减和0.9
的动量。Mask R-CNN 图像分割演示是用 Google Colab 编写的。
笔记本电脑加载示例图像并通过激活 TPU 创建 TensorFlow 会话。 然后加载预训练的模型蒙版 R-CNN,然后执行实例分割和预测。 该笔记本取自 Google Colab 网站,仅作了一项修改-图像加载函数。 下图显示了 Mask R-CNN 的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pbLgGWsq-1681784662639)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/e44dbd61-bc59-4d04-8207-5fc4e0e34536.png)]
Mask R-CNN 在前面概述的 Coco 数据集上进行了训练。 因此,human
,car
和traffic light
已经是为此预定的类。 每个人,汽车和交通信号灯都使用边界框进行检测,并使用分段绘制形状。
对象跟踪从对象检测开始,为每次检测分配一组唯一的 ID,并在对象四处移动时保持该 ID。 在本节中,将详细描述不同类型的对象跟踪模型。
顾名思义,基于质心的跟踪涉及跟踪使用阈值处理开发的图像群集的质心。 在初始化时,将 ID 分配给边界框形心。 在下一帧中,通过查看两个帧之间的相对距离来分配 ID。 当对象相距很远时此方法有效,但是当对象彼此非常靠近时该方法不起作用。
SORT 是由 Alex Bewley,Zongyuan Ge,Lionel Ott,Fabio Ramos 和 Ben Upcroft 在其名为《简单在线和实时跟踪》的论文中提出的。 本文使用 Faster R-CNN 进行检测,而卡尔曼过滤器和匈牙利算法用于多目标跟踪(MOT)进行实时。 跟踪实现的详细信息可以在这个页面中找到。
在 CVPR 2017 上,Nicolai Wojke,Alex Bewley 和 Dietrich Paulus 在他们的论文中提出了 DeepSORT 跟踪,其论文标题为《使用深度关联指标的简单在线和实时跟踪》。 可以在这个页面中找到该论文的详细信息。
DeepSORT 是 SORT 的扩展,并使用经过训练以区分行人的 CNN 将外观信息集成到边界框中。 跟踪实现的详细信息可以在这个页面中找到。
该架构的细节概述如下:
(u, v, γ, h, x, y, γ, h)
上定义的,其中(u, v)
是边界框中心位置,γ
是长宽比,h
是高度。k
,在卡尔曼过滤器预测期间对帧数进行计数和递增,并在对象检测期间将其重置为0
。 删除在前三个帧内超过阈值或与检测无关的轨道。OpenCV 具有许多内置的跟踪方法:
OpenCV 中上述方法的实现如下:
tracker = cv2.TrackerBoosting_create()
tracker = cv2.TrackerCSRT_create()
tracker = cv2.TrackerKCF_create()
tracker = cv2.TrackerMedianFlow_create()
tracker = cv2.TrackerMIL_create()
tracker = cv2.TrackerMOSSE_create()
tracker = cv2.TrackerTLD_create()
Luca Bertinetto,Jack Valmadre,Joao F. Henriques,Andrea Vedaldi 和 Philip HS Torr 在其具有里程碑意义的论文《用于目标跟踪的全卷积连体网络》中提出了基于连体网络的对象跟踪。 可以在这个页面上找到该论文的详细信息。
在本文中,作者训练了一个深度卷积网络以离线开发相似性函数,然后将其应用于实时对象跟踪。 相似度函数是连体 CNN,将测试边界框与训练边界框(真实情况)进行比较并返回高分。 如果两个边界框包含相同的对象且分数较低,则对象不同。
连体网络通过相同的神经网络传递两个图像。 它通过删除最后一个全连接层来计算特征向量,这在“第 6 章”,“使用迁移学习的视觉搜索”中进行了描述。 然后比较两个特征向量的相似性。 所使用的连体网络没有任何全连接层。 因此,仅使用卷积过滤器,因此网络相对于输入图像是完全卷积的。 全卷积网络的优点是它与大小无关。 因此,任何输入尺寸均可用于test
和train
图像。 下图说明了连体网络的架构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0hJ7r7gQ-1681784662639)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/c5197e16-6f1d-47e0-875c-e2e789f29750.png)]
在该图中,网络的输出是特征映射。 通过 CNN(f[θ]
)重复该过程两次,一次分别进行测试(x
)和训练(z
)。 图像,生成两个相互关联的特征映射,如下所示:
g[θ](z, x) = f[θ](z) * f[θ](x)
跟踪开始如下:
初始图像位置 = 先前的目标位置
位移 = 跨步乘以最大得分相对于中心的位置
新位置 = 初始位置 + 位移
因此,矩形边界框用于初始化目标。 在每个后续帧,使用跟踪来估计其位置。
在 CVPR 2019 上,王强,张立,Luca Bertinetto,胡卫明和 Phillip H.S.Torr 在他们的论文《快速在线对象跟踪和分段:统一方法》中提出了 SiamMask。 有关本文的更多详细信息,请参见这里。
SiamMask 使用单个边界框初始化并以每秒 55 帧的速度跟踪对象边界框。
在此,将连体网络的简单互相关替换为深度相关,以生成多通道响应图:
1 x 1
卷积神经网络hf
设计w x h
二元掩码(每个特征映射一个)。 第一层具有 256 个通道,第二层具有1 x 1
通道。1 x 1
卷积层结束。 请注意,ResNet-50 具有四个阶段,但仅考虑了前三个阶段,并且对跨步 1 的卷积进行了修改,以将输出跨步减小到 8。1 x 1
卷积。可在这里 上找到有关 SiamMask 实现以及训练的详细信息。 SiamMask 也可以在这个页面上使用。 请注意,为了使其成功运行,视频文件必须以人像开头。
在本章中,您将从头到尾全面了解各种对象检测器方法以及使用自己的自定义图像训练对象检测器的实用方法。 学习到的一些关键概念包括如何与 Google Cloud 一起使用以评估对象检测器,如何使用labelImg
创建标注文件,如何将 Google Drive 链接到 Google Colab 笔记本以读取文件,如何生成 TensorFlow .xml
和.jpg
文件中的tfRecord
文件,如何开始训练过程并在训练过程中监控读数,如何创建 TensorBoard 以观察训练准确率,如何在训练后保存模型以及如何通过保存的模型进行推断。 使用这种方法,您可以选择对象类并创建用于推理的对象检测模型。 您还学习了各种对象跟踪技术,例如 Kalman 滤波和基于神经网络的跟踪,例如 DeepSORT 和基于连体网络的对象跟踪方法。 下一步,可以将对象检测模型连接到跟踪方法以跟踪检测到的对象。
在下一章中,我们将通过在边缘设备(例如手机)中优化和部署神经网络模型来学习边缘计算机视觉。 我们还将学习如何使用 Raspberry Pi 进行实时对象检测。
在本部分中,您将使用到目前为止获得的所有计算机视觉和 CNN 知识,在边缘设备中打包,优化和部署模型,以解决现实生活中的计算机视觉问题。 在本地计算机上训练大型数据集需要花费时间,因此您将学习如何打包数据并上传到云中的容器,然后开始训练。 您还将看到如何克服一些常见的错误以完成训练并成功生成模型。
在本节结束之前,您将能够执行以下操作:
本节包括以下章节:
到目前为止,我们已经学习了如何通过预处理数据,训练模型以及使用 Python PC 环境生成推论来开发深度学习模型。
在本章中,我们将学习如何采用生成的模型并将其部署在边缘设备和生产系统上。 这将导致完整的端到端 TensorFlow 对象检测模型实现。 本章将讨论许多边缘设备及其标称性能和加速技术。
特别是,使用 TensorFlow Lite 和 Intel 开放视觉推断和神经网络优化(VINO)架构,并部署到 Raspberry Pi,Android 和 iPhone。 尽管本章主要关注 Raspberry Pi,Android 和 iPhone 上的对象检测,但我们将介绍的方法可以扩展到图像分类,样式迁移和所考虑的任何边缘设备的动作识别。
本章分为以下几节:
对于计算机而言,边缘是查看事物并测量参数的最终设备。 在边缘设备上进行深度学习意味着将 AI 注入到边缘设备中,以便与视觉一起还可以分析图像并报告其内容。 用于计算机视觉的边缘设备的示例是照相机。 边缘计算使本地图像识别快速有效。 摄像头内的 AI 组件由功能强大的微型处理器组成,该处理器具有深度学习功能。
取决于所使用的硬件和软件平台的选择,边缘的 AI 可以执行三种独立功能的组合:
这样做的好处是提高了速度,减少了带宽,增加了数据保密性和网络可伸缩性。 这是通过在相机内部嵌入一个控制器来赋予相机所需的处理能力来完成的。
边缘计算意味着将工作负载从云转移到设备。 这就需要高效的边缘设备,优化的软件来执行检测而不会出现明显的延迟,以及高效的数据传输协议,以将选择的数据发送到云中进行处理,然后将输出反馈到边缘设备以进行实时决策。 选择正确的边缘设备取决于您的应用要求及其与子系统其余部分的接口方式。 边缘设备的一些示例如下:
下表总结了前面列出的各种边缘设备的性能规格。 您可以使用此表来确定选择过程:
装置 | GPU | CPU | 内存 | 加速器 |
---|---|---|---|---|
NVIDIA Jetson Nano 69 毫米 x 45 毫米 | 128 核 NVIDIA Maxwell | 四核 ARM Cortex A57 | 4 GB RAM,16 GB 存储 | 并行处理器 |
Raspberry Pi 4 85 毫米 x 56 毫米 | 1.5 GHz 时的 ARM Cortex A72 | 4 GB RAM,32 GB 存储 | ||
Coral 开发板 48 毫米 x 40 毫米 | 集成的 GC7000 Lite 图形 | 四核 Cortex-A53,加上 Cortex-M4F | 1 GB LPDDR4 | Google Edge TPU ML 加速器协处理器 |
Orange Pi 85 毫米 x 55 毫米 | ARM Mali-400 MP2 GPU @ 600MHz | 4 个 Cortex-A7 @ 1.6 GHz | 1 GB DDR3 SDRAM | |
ORDOID C2 85 毫米 x 56 毫米 | Mali 450MP3 | ARM Cortex-A53 四核 @ 1.5 GHz | 2 GB DDR3 SDRAM | |
英特尔神经网络棒 | 英特尔 Movidius Myriad X 视觉处理单元(VPU),具有 16 个处理核心和一个网络硬件加速器 | 英特尔 OpenVINO 工具包 | ||
Coral USB 加速器 | Google Edge TPU ML 加速器协处理器,支持 AUTOML Vision Edge | TensorFlow Lite 模型支持 | ||
Android Pixel XL 155 毫米 x 76 毫米 | Ardeno 530 | 2 个 2.15 GHz Kryo 和 2 个 1.6 GHz Kryo | 4 GB 内存 | |
iPhone XR 155 毫米 x 76 毫米 | A12 仿生芯片 | A12 仿生芯片 | 3 GB 内存 |
中央处理器(CPU)主要执行串行处理,而图形处理器(GPU)并行运行进程并且可以一次执行大量操作,从而加快了处理速度。 GPU 中的数据称为线程。 使用计算统一设备架构(CUDA)和开放计算语言(OpenCL)对 GPU 进行编程。 CPU 执行许多不同类型的计算,而 GPU 专门处理给定的计算,例如图像处理。 为了使边缘设备提供无延迟的结果,它们必须伴随加速器,GPU 和软件优化。
以下是一些通常用于 GPU/CPU 优化的方法:
Google 的一个团队在 CVPR 2017 中的题为《MobileNets:针对移动视觉应用的高效卷积神经网络》中介绍了 MobileNet。 您可以在这个页面上找到此 MobileNet 论文。
MobileNet 提出了一种深度可分离的卷积架构,该架构缩小了神经网络模型,以便可以处理边缘设备的资源限制问题。 MobileNet 架构包括两个主要部分:
1 x 1
卷积请注意,我们在“第 4 章”,“图像深度学习”和“第 5 章”,“神经网络架构和模型”中描述了1 x 1
卷积的重要性。 您可能需要重新阅读这些章节。
下图显示了深度卷积的工作方式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2izNPwOe-1681784662640)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/08af9c03-40d5-4011-b437-39eb0e08a60c.png)]
在上图中,我们可以看到以下内容:
Raspberry Pi 是没有 GPU 的单板微型计算机,可以连接到外部相机和其他传感器模块,并且可以用 Python 编程以执行计算机视觉工作,例如目标检测。 Raspberry Pis 具有内置的 Wi-Fi,因此它们可以无缝连接到互联网以接收和传输数据。 由于其纤巧的外形和强大的计算能力,Raspberry Pi 是用于物联网和计算机视觉工作的边缘设备的完美示例。 可以在这个页面上找到有关 Raspberry Pi 的详细信息。 下图显示了 Raspberry Pi 的完整设置:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KvYBmKz0-1681784662640)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/2dab1ebe-b2b9-4fb6-b3f4-948c143b26cd.png)]
以下各节将介绍 Raspberry Pi 的详细硬件设置。
请注意,此图像将在以下设置部分中多次列出。
以下是开始 Raspberry Pi 设置工作之前要考虑的一些重要点:
在本节中,我们将研究为了建立用于计算机视觉的 Raspberry Pi 而需要的 Python 中的各个代码段。
我们可以将相机设置为视频播放器。 在 Raspberry Pi 终端中一一使用以下命令。 这些命令将进行必要的包更新,并启动新的 Raspbian 安装:
$sudo apt update
$sudo apt full-upgrade
$sudo raspi-config
输入最后一个命令后,Raspberry Pi 中将出现一些对话框。 选择必要的接口选项,选择一个摄像机,然后单击“是”是否要启用摄像机接口? 然后,重新启动 Raspberry Pi,并在启动后在终端中输入以下命令:
$raspivid -o video.h264 -t 10000
您会注意到视频录制了 10 秒钟并以video.h264
格式保存。 第一次执行此操作时,您会发现相机未对准焦点。 调整相机上的圆帽(取下盖子后),直到其对准焦点。
到此结束如何设置相机软件。 如果要了解有关此过程的更多信息,请参考这里。
有关详细说明,请转到这里。
在安装过程中,我发现必须在多个页面之间导航才能正确处理所有问题。 以下是对我有用的分步说明。 欢迎您使用官方网站或此处给出的说明以使所有东西正常运行:
以下每一行都是单独的指令。 这意味着要输入一个命令,请按Enter
并等待其显示在控制台中,表明已完成,然后再输入下一个命令。
$sudo su
$apt update && apt upgrade –y
$apt install build-essential
$wget https://github.com/Kitware/CMake/releases/download/v3.14.4/cmake-3.14.4.tar.gz
$tar xvzf cmake-3.14.4.tar.gz
$cd ~/cmake-3.14.4
bootstrap
:$./bootstrap
$make –j4
$make install
$git clone https://github.com/opencv/opencv.git
$cd opencv && mkdir build && cd build
$cmake –DCMAKE_BUILD_TYPE=Release –DCMAKE_INSTALL_PREFIX=/usr/local ..
$make –j4
$make install
上面的命令将安装 OpenCV。
$python3
>>> import cv2
>>> cv2.__version__
这应该显示系统上安装的最新 OpenCV 版本。
OpenVINO 是 Intel 的商标,代表 Open Visual Inference 和 Neural Network Optimization 工具包。 它为开发人员提供了基于 Intel 硬件的深度学习加速工具包,例如 CPU(Intel Core 和 Xeon 处理器),GPU(Intel Iris Pro 图形和 HD 图形),VPU(Intel Movidius 神经计算棒)和 FPGA(Intel Arria 10GX)。 。
要在桌面上下载 OpenVINO,请转到这里。
下载 OpenVINO 之后,您将必须输入您的姓名和电子邮件。 然后,您将能够下载 OpenVINO。 按照说明解压缩文件并安装依赖项。 请注意,此过程不适用于 Raspberry Pi。 因此,对于 Raspberry Pi,请使用以下命令:
$cd ~/dldt/inference-engine
$mkdir build && cd build
$cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS='-march=armv7-a' \
-DENABLE_MKL_DNN=OFF \
-DENABLE_CLDNN=OFF \
-DENABLE_GNA=OFF \
-DENABLE_SSE42=OFF \
-DTHREADING=SEQ \
..
$make
前面的命令将在终端中返回一系列显示。
要安装 OpenVINO 工具包组件,请转到这里。
已列出以下步骤作为参考:
sudo su
,然后按Enter
。
R3 l_openvino_toolkit_runtime_raspbian_p_2019.3.334.tgz
。 请注意,p_
和before.tgz
之后的数字在将来的版本中可能会更改。
$sudo mkdir -p /opt/intel/openvino
$sudo tar -xf l_openvino_toolkit_runtime_raspbian_p_2019.3.334.tgz --
$strip 1 -C /opt/intel/openvino
sudo apt install cmake
通过设置环境变量,每次启动终端时,OpenVINO 都会被初始化。 这使您不必每次都记住命令提示符。
您可以在以下步骤的帮助下本地设置环境变量或全局设置环境变量:
$source /opt/intel/openvino/bin/setupvars.sh
$echo "source /opt/intel/openvino/bin/setupvars.sh" >> ~/.bashrc
[setupvars.sh] OpenVINO environment initialized
Pi$raspberripi: $
Type sudo su and you should get
root@raspberripi:
需要 USB 规则才能在 Intel Movidius 神经计算棒上进行推理。 按着这些次序:
$sudo usermod -a -G users "$(whoami)"
sh /opt/intel/openvino/install_dependencies/install_NCS_udev_rules.sh
完成所有安装过程后,下一个任务是使用通过相机模块连接到 Raspberry Pi 的 Intel Movidius 神经计算棒进行推理。 此处的摄像头模块是边缘设备,而带有英特尔 Movidius 神经计算棒的 Raspberry Pi 是处理器单元。
请注意,Raspberry Pi 本身无法通过神经网络执行推理,因为处理速度非常慢。 使用英特尔 OpenVINO 神经计算棒,您会看到很少的延迟。 作为比较,请参考“使用 TensorFlow Lite 在 Raspberry Pi 上进行对象检测”,其中使用 tflite 在没有神经网络棒的情况下将 TensorFlow 模型部署到 Raspberry Pi。 您会注意到,在这种情况下,延迟是很大的。
让我们看一下以下命令:
$mkdir build && cd build
$cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-march=armv7-a" /opt/intel/openvino/deployment_tools/inference_engine/samples
$make -j2 object_detection_sample_ssd
$wget --no-check-certificate https://download.01.org/opencv/2019/open_model_zoo/R1/models_bin/face-detection-adas-0001/FP16/face-detection-adas-0001.bin
$wget --no-check-certificate https://download.01.org/opencv/2019/open_model_zoo/R1/models_bin/face-detection-adas-0001/FP16/face-detection-adas-0001.xml
运行openvino_fd_myriad.py
文件中提供的示例代码,如下所示:
python3 openvino_fd_myriad.py
请参阅以下 GitHub 页面以获取完整代码。 另外,查看out.png
文件以查看在图像上绘制的边界框。
到目前为止,我们刚刚使用 OpenVINO 工具包执行了面部检测。 在本节中,我们将学习如何使用连接到 Raspberry Pi 的 Intel Movidius 神经网络棒执行各种计算机视觉任务,例如行人检测,车辆和自行车检测,车牌检测,年龄和性别识别,面部标志识别 ,情感识别,姿势估计,动作识别,注视识别等。
英特尔开源技术中心提供了我们将使用的所有bin
和xml
文件的列表。 。
请注意,当您单击上一个链接时,将看到四个标记为R1, R2, R3, and R4
的文件夹。 单击一个具有最新日期的日期,在这种情况下为R1
。 在以下屏幕截图中可以看到:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vXi2bz2M-1681784662640)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/1f5f007f-c2c0-46bc-8934-ac59097065c8.png)]
然后,单击最新文件夹,在这种情况下为models_bin
。 这将打开一个对话框,显示FP16
,FP32
或INT8
。 对于某些模型,不提供INT8
。
现在,让我们尝试了解这些参数的含义,以便我们可以根据自己的具体应用选择合适的参数。 FP16
将 16 位而不是 32 位用于FP32
,从而减少了训练和推理时间。 另一方面,INT8
使用 8 位整数对神经网络进行权重,梯度和激活的训练。 因此,在这三种方法中,INT8
应该是最快的一种,英特尔声称它仍然保持准确率。
如果您想了解有关英特尔使用的 8 位训练方法的更多信息,请参阅标题为《神经网络的 8 位训练的可扩展方法》的论文,该论文发表在这里。 为了在 Raspberry Pi 等边缘设备上更快地进行处理,建议的方法是使用FP16
或INT8
(如果有)。
先前描述的开放模型动物园具有各种预先构建的模型,例如用于人脸检测,人检测,自行车检测等的模型。 这些模型已经过训练,因此我们将在本章中仅出于推理目的使用这些模型。 如果您想了解训练方法,则可以按照“第 10 章”,“使用 R-CNN,SSD,和 R-FCN”。
接下来,我们将看一些将模型分为四种类型的表。
下表描述了各种面部检测,人员检测以及车辆和自行车检测模型。 请仔细注意表中列出的每个模型的输入和输出,因为需要在 Python 代码中输入这些信息以进行推断:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mPaWIIfq-1681784662640)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/fe5c3606-c529-47cc-90c8-1fbb9a3cf358.png)]
我们可以看到,尽管模型类型不同,但输入本质上是相同的。 唯一的区别是输入图像的尺寸。 输出也相同–它们都生成一个矩形边界框。
下表描述了用于年龄性别和情感识别,面部标志识别,车辆颜色和类型识别以及人的属性(例如衬衫,帽子和背包)的模型。 请注意表中列出的每个模型的输入和输出,因为这需要在 Python 代码中输入以进行推断:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YxYDuPfs-1681784662640)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/4bfb353a-f606-47ac-bced-ec27c98aea28.png)]
在这里,输入是相同的:不同模型的尺寸不同,但是输出却不同。 对于地标,输出可以是面部轮廓的 5 点或 35 点。 对于人员属性,输出可以是八个属性中每个属性的二进制结果。 车辆属性可以是颜色或类型,而情感属性将导致五个类别中每个类别的概率。
下表描述了用于姿势估计和动作识别的模型。 请注意表中列出的每个模型的输入和输出,因为这需要在 Python 代码中输入以进行推断:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SZncke4q-1681784662641)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/ec8456e7-7202-4546-b63c-329915441c14.png)]
上表显示,所有模型的输入结构均相同,只是图像形状有所变化。 姿势识别的输出显示三个角度:偏航,横摇和俯仰。
最后,下表显示了车牌,注视估计和人员检测的多输入 Blob:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C7ZM5hnS-1681784662641)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/aab4bbfe-5f81-4980-aae3-a30bbeb9c4a4.png)]
以下代码概述了前两个表的主要组成部分; 即,用于面部检测,人物检测,汽车检测和地标检测。 让我们来看看:
cvNet = cv2.dnn.readNet('face-detection-adas-0001.xml', 'face-detection-adas-0001.bin')
cvNet.setPreferableTarget(cv2.dnn.DNN_TARGET_MYRIAD)
cvLmk = cv2.dnn.readNet('facial-landmarks-35-adas-0002.xml','facial-landmarks-35-adas-0002.bin')
cvLmk.setPreferableTarget(cv2.dnn.DNN_TARGET_MYRIAD)
ret, frame = cam.read()
rows = frame.shape[0]
cols = frame.shape[1]
blobFromImage
函数从给定大小和深度的帧中提取一个四维斑点。 请注意,斑点的大小应等于上表中列出的相应模型中指定的输入大小。 对于人脸检测,斑点输入大小为(672, 384)
,因此斑点表达式编写如下: cvNet.setInput(cv2.dnn.blobFromImage(frame, size=(672, 384), ddepth=cv2.CV_8U))
cvOut = cvNet.forward()
对于界标检测,斑点输入大小为(60, 60)
,因此斑点表达可以表示为:
cvLmk.setInput(cv2.dnn.blobFromImage(frame, size=(60, 60), ddepth=cv2.CV_8U))
lmkOut = cvLmk.forward()
完成前面的步骤后,我们可以继续并绘制输出以进行可视化。 这是通过带有嵌套循环的两个for
语句执行的:
for
语句使用xmin, ymin, xmax, and ymax
查找矩形边界框坐标,如果confidence > 0.5
则使用cv2.rectangle
创建矩形。for
语句在面边界框内绘制 35 个圆,其x
和y
坐标如下:x = xmin + landmark output (i) * (xmax-xmin)
y = ymin + landmark output (i) * (ymax-ymin)
现在,我们可以使用cv2.circle
绘制圆。 下面的代码总结了这一原理,在其中绘制了面部标志。 请注意我们前面讨论的两个for
语句:
# Draw detected faces on the frame.
for detection in cvOut.reshape(-1,7):
confidence = float(detection[2])
xmin = int(detection[3] * cols)
ymin = int(detection[4] * rows)
xmax = int(detection[5] * cols)
ymax = int(detection[6] * rows)
if confidence > 0.5 :
frame = cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), color=(255, 255, 255),thickness = 4)
for i in range(0, lmkOut.shape[1], 2):
x, y = int(xmin+lmkOut[0][i]*(xmax-xmin)), ymin+int(lmkOut[0][i+1]*(ymax-ymin))
# Draw Facial key points
cv2.circle(frame, (x, y), 1, color=(255,255,255),thickness = 4)
尽管此处描述的代码讨论了面部标志和面部检测,但是可以更新相同的 Python 代码,以便我们可以执行其他任何类型的检测,例如车牌,人,自行车等。 您需要做的就是通过更改设置的输入来更改输入,然后调整for
语句值。 此面部关键点检测示例是一个涉及面部和界标检测的复杂示例,这就是为什么使用两个for
循环语句的原因。 例如,在车牌检测中,您只需要使用一个for
循环语句。
现在,让我们学习使用 OpenVINO 进行推理。
本节讨论如何使用预训练模型或定制训练模型来使用 OpenVINO 进行推理。 推理是使用模型执行对象检测或分类的过程,分为三个步骤:
以下各小节将详细讨论这些步骤。
如前所述,OpenVINO 为 Raspberry Pi 安装的工具包与在普通 PC 上的安装方法不同。 Raspberry Pi 的安装不包括 Model Optimizer。 神经计算应用动物园(NCPAppZoo)是一个开放源代码存储库。 让我们看一下如何使用 ncappzoo:
cd ~ git clone https://github.com/opencv/dldt.git dldt/model-optimizer pip3 install -r requirements_tf.txt
repo
:$git clone https://github.com/movidius/ncappzoo.git
/ncappzoo/apps/
,找到相关的app
文件夹目录,然后执行以下命令:$make run
这将打开一个窗口,我们可以在该窗口上显示图像。
本部分描述了转换自定义 TensorFlow 模型的步骤,它们使用我们在“第 6 章”,“使用迁移学习的视觉搜索”中开发的 TensorFlow Keras 对象分类模型,或使用 TensorFlow 对象检测 API,就像我们在上一章中所做的那样。 如果您已经计划使用来自英特尔开放源技术中心的经过预先训练的优化模型,那么上一节中描述的步骤将起作用。 在下一节中,我们将描述如何使用两种类型的 TensorFlow 模型执行转换。
本节介绍如何将 TensorFlow 模型转换为 OpenVINO IR 格式。 有关更多信息,请参考以下链接。
这些步骤可以总结如下:
<INSTALL_DIR>/deployment_tools/model_optimizer/install_prerequisites directory and run: $install_prerequisites.sh
xml
文件和bin
文件。 转换是通过mo.py
工具完成的,如以下代码所示:Go to the <INSTALL_DIR>/deployment_tools/model_optimizer directoryin the Terminal and execute
$python3 mo_tf.py --input_model <INPUT_MODEL>.pb
在冻结模型开发过程中指定以下参数并理解它们非常重要,因为mo.py
工具有时会在冻结模型中找不到时产生错误:
input_model
:正在使用的预训练模型的名称input_shape
:例如[1,300,300,3]本节介绍如何转换使用 TensorFlow 对象检测 API 创建的冻结图。 如果使用 TensorFlow 对象检测 API 开发模型,则详细过程与我们在上一节中介绍的过程不同。 可以在这里中找到更多信息。
我们已经冻结了使用 TensorFlow 对象检测 API 在“第 10 章”,“使用 R-CNN,SSD 和 R-FCN”进行对象检测的模型。 请按照以下步骤进行转换:
.pb
扩展名的文件,是通过使用自定义图像训练模型(R-CNN,SSD 或 R-FCN)而生成的。 在此示例中,它是frozen_inference_graph_fasterRCNN.pb
。json
文件:这是相应的json
文件,该文件描述了冻结的 TensorFlow 图的自定义属性,节点,端口,端点和起点。faster_rcnn_inception_v2_pets.config.
完成上述步骤后,在终端中执行以下代码:
$python3 mo_tf.py --input_model frozen_inference_graph_fasterRCNN.pb --transformations_config faster_rcnn_support_api_v1.14.json --tensorflow_object_detection_api_pipeline_config faster_rcnn_inception_v2_pets.config
在这里,您需要将扩展名为.pb
的文件替换为扩展名为.pb
的特定模型文件名。 转换的结果将是xml
和bin
文件。
有了xml
和bin
文件后,我们就可以使用 Python 文件和“高级推断”部分中所述的说明来测试模型。
如果在调色时遇到问题,可以使用下面的 linbke 中显示的 OpenVINO 论坛,以查看类似问题的答案,也可以发布您的问题。
前面描述的整个模型推断过程可以用流程图表示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RiTXuWNQ-1681784662641)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/07f2001b-42f3-4d51-9779-d69cb44501e8.png)]
上图表明该过程可以分为三个关键部分:
make run
或使用 Python 代码执行推论。 我发现在 Intel PC 上,所有这些步骤都很容易执行。 但是,在 Raspberry Pi 环境中,使用make Run
命令在终端中进行操作会导致不同类型的错误。 例如,有时找不到.bin
或.xml
文件。 其他时间,环境变量未初始化或找不到CMakeLists.txt
文件。 执行提供的 Python 代码不会在 Raspberry Pi 中产生任何这些问题。 这也使我们对计算机视觉环境有了更好的了解,因为我们要做的只是获取模型,了解输入和输出,然后生成一些代码以便我们可以显示结果。
在继续下一节之前,让我们总结到目前为止所学的模型优化技术:
1)批量归一化操作与卷积操作融合-OpenVINO 使用它
2)将步长大于 1 并且过滤器大小为 1 的卷积移动到上层卷积层。 添加池化层以对齐输入形状-OpenVINO 使用它
3)用两个小过滤器替换大过滤器,例如将3 x 3 x 3
替换为#32
,将3 x 3 x 1
替换为#3
,将1 x 1 x 3
替换为#32
-MobileNet 使用它。
TensorFlow Lite 是用于边缘设备推理的 TensorFlow 深度学习框架。 与 OpenVINO 相似,TensorFlow Lite 具有内置的预训练深度学习模块。 或者,可以将现有模型转换为 TensorFlow Lite 格式以进行设备上推理。 目前,TensorFlow Lite 为具有内置或外部摄像头的 PC,Android 设备,iOS 设备,Raspberry Pi 和微型微控制器提供推理支持。 访问这里了解有关 TensorFlow Lite 的详细信息。
TensorFlow Lite 转换器采用 TensorFlow 模型并生成FlatBuffer tflite
文件。 FlatBuffer
文件是高效的跨平台库,可用于访问二进制序列化数据而无需解析。 序列化的数据通常是文本字符串。 二进制序列化数据是以字符串格式写入的二进制数据。 有关FlatBuffer
的详细信息,请参考以下链接。
TensorFlow 输出模型可以是以下类型:
tf.saved_model
执行保存的模型,输出为saved_model.pb
。 它是完整的 TensorFlow 格式,其中包括学习的权重和图结构。tf.keras
模型格式:tf.kears
模型是tf.keras.model.compile
文件,我们在“第 4 章”,“图像深度学习”和“第 6 章”,“使用迁移学习的视觉搜索”。本节将描述如何将 TensorFlow 模型转换为tflite
格式。 如果我们不这样做,那么我们开发的模型可以在本地 PC 中用于推理,但不能部署到边缘设备进行实时推理。 将针对此转换描述三种方法:
tflite
转换tflite
转换的 Google Colabtoco
由于这是对象检测转换,因此我们的模型是根据 TensorFlow 对象检测 API 开发的,因此我们将在 Google Colab 中使用toco
方法。
Python API 使我们可以轻松使用 TensorFlow Lite 转换器。 在本节中,我们将描述使用 tflite 转换器的 Python API。 有关更多信息,请参考以下链接。
根据所使用的转换器类型,建议了三种方法–保存的模型,Keras 模型或具体函数。 以下代码显示了如何从 Python API 调用tf.lite.TFLiteConverter
来转换三个模型(保存模型,Keras 模型或具体函数)中的每个模型:
$import tensorflow as tf
$converter = tf.lite.TFLiteConverter.from_saved_model(export_dir)
$converter = tf.lite.TFLiteConverter.from_keras_model(model)
$converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func])
tflite_model = converter.convert()
接下来,我们将学习如何使用 TensorFlow 对象检测 API 转换在“第 10 章”,“使用 R-CNN,SSD 和 R-FCN 的对象检测”中开发的训练模型。 Google Colab 使用两种不同的方法-tflite_convert
和toco
。
tflite_convert
在以下代码中,我们定义了冻结模型.pb
文件和相应的tflite
文件的位置。 然后,我们将三个 RGB 轴的每一个的输入彩色图像的大小调整为(300, 300)
,并将图像转换为归一化张量,然后将其变为转换的输入数组。 有四个输出数组,它们的定义如下:
TFLite_Detection_PostProcess
—检测盒TFLite_Detection_PostProcess:1
-检测类别TFLite_Detection_PostProcess:2
-检测分数TFLite_Detection_PostProcess:3
-检测次数!tflite_convert \
--graph_def_file=/content/models/research/fine_tuned_model/tflite_graph.pb \
--output_file=/content/models/research/fine_tuned_model/burgerfries.tflite \
--output_format=TFLITE \
--input_shapes=1,300,300,3 \
--input_arrays=normalized_input_image_tensor \
--output_arrays= 'TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' \
--change_concat_input_ranges=false \
--allow_custom_ops
TOCO 代表 TensorFlow 优化转换器。 要了解对 TOCO 的详细了解,请访问以下 GitHub 页面。
以下代码描述了如何使用 TOCO 转换 TensorFlow 模型。 除了使用toco
而不是tflite
之外,代码的第一部分与之前的内容相同。 下一部分使用量化推断类型。 量化是一个过程,用于减小模型大小,同时改善硬件加速延迟。 有多种量化方法,如这个页面中所述。
在这种情况下,我们使用完整的整数量化。 没有使用反量化,但是平均值和标准差值用于确定推理代码中的定点乘数:
"!toco \\\n",
"--graph_def_file=\"/content/models/research/fine_tuned_model/tflite_graph.pb\" \\\n",
"--output_file=\"/content/models/research/fine_tuned_model/burgerfries_toco.tflite\" \\\n",
"--input_shapes=1,300,300,3 \\\n",
"--input_arrays=normalized_input_image_tensor \\\n",
"--output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' \\\n",
"--inference_type=QUANTIZED_UINT8 \\\n",
"--mean_values=128 \\\n",
"--std_dev_values=128 \\\n",
"--change_concat_input_ranges=false \\\n",
"--allow_custom_ops"
可以在以下 GitHub 链接中找到用于训练和转换的 Google Colab 笔记本的详细信息。
注意,在两个模型之间,我们使用了 TOCO。 原因是使用 tflite 时,转换后的模型不会在 Android 手机上检测到边界框。
TensorFlow 模型可以表示为已保存的模型或 Keras 模型。 以下代码显示了如何将模型另存为已保存的模型或 Keras 模型:
model.save
函数启动:tf.saved_model.save(pretrained_model, "/tmp/mobilenet/1/")
tf.saved_model.save(obj, export_dir, signatures=None, options=None)
history.fit
命令编译 Keras 模型并准备进行训练。 请注意,我们在“第 4 章”,“图像深度学习”和“第 6 章”,“使用迁移学习的视觉搜索”中对此进行了编码练习。 :model.compile(loss='sparse_categorical_crossentropy', optimizer=keras.optimizers.RMSprop())
history = model.fit(x_train, y_train, batch_size=64, epochs=20)
model.save('path_to_my_model.h5')
可以通过训练后量化来执行模型优化(也称为量化),以提高 CPU/GPU 性能,而不会牺牲准确率。 可以使用以下方法执行优化过程:
from tensorflow_model_optimization.sparsity import keras as sparsity
pruning_params = {
'pruning_schedule': sparsity.PolynomialDecay(initial_sparsity=0.50,
final_sparsity=0.90,
begin_step=end_step/2,
end_step=end_step,
frequency=100)
}
l = tf.keras.layers
sparsity.prune_low_magnitude(l.Conv2D(64, (3, 3), activation='relu'),**pruning_params
有关详细信息,请访问 TensorFlow 网站。
请注意,在上一节中讨论了使用 Google Colab 对使用 TOCO 的对象检测模型进行的模型优化。
在以下代码中,我们正在优化保存的模型的大小,从而将最终输出模型减小到其原始大小的 1/3 或 1/4:
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
tflite_quant_model = converter.convert()
以下代码描述了完整的整数量化以及大小的优化:
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
tflite_quant_model = converter.convert()
本节将介绍部署 TensorFlow lite 转换模型所需的步骤。 或者,您可以按照这个页面上的说明来构建示例应用。 有关 Android 手机上对象检测的详细流程图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hJgTizD0-1681784662641)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/20e25d76-69c4-408e-959e-e79140a129bb.png)]
我们需要两个文件:
.tflite
格式的文件.txt
文件显示了该类如果我们导出.tflite
文件,则直接来自 Google Colab,如“TensorFlow 对象检测 API – TOCO”部分中所述。 lablemap.txt
文件来自label_map.pbtxt
文件,仅列出了类的名称。
在 Android 手机中采用tflite
模型并生成推理的步骤如下:
.txt
文件将具有一列和两行,如下所示: burger
fries
android-studio/bin
目录并键入./studio.h
。
git clone https://github.com/tensorflow/examples
。
examples/lite/examples/object_detection/android
。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-phCuhJkE-1681784662642)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/780b2705-5d24-4741-9bdc-51821712e470.png)]
.tflite
和.txt
文件拖放到资产目录中。 关闭文件夹,然后返回 Android Studio。.txt
文件将其打开,并在顶部添加新行。 用???
填充它。 因此,.txt
文件将为这两个类提供三行:???
Burger
fries
Java
,然后选择跟踪,然后双击DetectorActivity
。 将.tflite
和.txt
文件的名称更改为其实际名称,如以下屏幕截图所示。 然后,点击build gradle
:请注意,对于.txt
文件,请保留路径,即file:///android_asset/burgerfries_labelmap.txt
。 稍后,我们将提到,如果未使用toco
生成.tflite
文件,则保留先前的路径将导致应用崩溃。 为了防止崩溃,您可以仅保留文件名(例如burgerfries_labelmap.txt
)。 但是,请注意,这不会为检测到的图像创建边界框。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lhXbaHE7-1681784662642)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/91b37b72-690b-46c9-b2d8-7dbb92c321db.png)]
///apply from download_model.gradle
。 验证依赖性是否出现,如前面的屏幕快照所示。
ok
即可运行该应用。 以下是该应用工作的图像:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NTZ2j6Sn-1681784662642)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/ae5a9279-2ad0-40da-869f-8e2738873476.png)]
如我们所见,该电话能够以非常高的准确率清晰地检测汉堡和薯条的真实图像。 至此,Android 应用部署练习结束。
TensorFlow Lite 下列出的 Python quickstart
包描述了如何为 Raspberry Pi 安装 TensorFlow Lite 包。 但是,有几个值得注意的例外。 因此,我们在此处列出了整个过程:
$sudo su
$pip3 install tflite_runtime-1.14.0-cp37-cp37m-linux_armv7l.whl
label_image.py
文件中进行一些更改:$import tflite_runtime.interpreter as tflite,
$interpreter = tf.lite.Interpreter(model_path=args.model_file)
请注意,当在 Raspberry Pi 4 中进行了这些更改并且在终端中通过键入python3 label_image.py
执行代码时,将发生错误,指出即使安装了 Python,也找不到 TensorFlow Lite 解释器。 对 Raspberry Pi 3 重复了上述步骤,没有发生错误。
pi/examples/lite/examples
的目录。 在此文件夹中,您应该具有诸如image_classification
,object_detection
,image_segmentation
,posenet
和style_transfer
等目录。现在,让我们执行以下步骤进行图像分类:
image_classification
目录,即pi/examples/lite/examples/image_classification/raspberry_pi
。 您将看到一个名为classify_picamera.py
的文件。 现在,转到这里并下载对象检测模型以及名为mobilenet_v2_1.0_224.tflite
和labels_mobilenet_v2_1.0_224.txt
的label
文件文件夹。 将这些文件复制到pi/examples/lite/examples/image_classification/raspberry_pi
中。
pi/examples/lite/examples/image_classification/raspberry_pi
使用终端转到目录并执行以下命令:
$Python3 classify_picamera.py –model mobilenet_v2_1.0_224.tflite –labels labels_ mobilenet_v2_1.0_224.txt
在 Raspberry Pi 上安装 TensorFlow lite 之后,我们现在可以执行对象检测。 按着这些次序:
pi/examples/lite/examples/object_detection/raspberry_pi
。 您将看到一个名为detect_picamera.py
的文件。coco_ssd_mobilenet_v1_1.0_quant_2018_06_29
的对象检测模型和标签文件文件夹。 在此文件夹中,您将看到两个文件:detect.tflite
和labelmap.txt
。pi/examples/lite/examples/object_detection/raspberry_pi
中。pi/examples/lite/examples/object_detection/raspberry_pi
使用终端转到对象检测目录,并执行以下命令:$Python3 detect_picamera.py –model detect.tflite –labels labelmap.txt
现在,您应该看到 Raspberry Pi 摄像头模块亮起并开始在图像周围显示边框。
burgerfries.tflite
和labelmap
文件复制到文件夹中。 然后,更改前面命令行中显示的 Python 路径以反映您的新文件名并执行它。 以下图像是用于object_detection
的图像:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-paeP5Qz6-1681784662642)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/c324b898-4e23-407f-aa23-2a59ee6f2915.png)]
这里有几件事要注意:
该示例清楚地显示了相同模型在不同设备上的行为方式不同。
在 2020 TensorFlow 开发峰会上,TensorFlow 工程师宣布将显着改善延迟-浮点 CPU 执行为 55 ms 至 37 ms,定量定点 CPU 执行为 36 ms 至 13 ms,OpenCL 为 20 ms 至 5 ms 浮动 16 GPU 执行,2 ms 用于量化定点 Edge TPU 执行。 在进行此更改之前,对仅具有 CPU 的 Raspberry Pi 进行了测试。 因此,由于上述更改,您应该在 Raspberry Pi 上看到性能上的改进。 TF Lite 2.3 将带来进一步的改进。
到目前为止,我们已经学习了如何将 TensorFlow 模型转换为 tflite 格式并在 Android 手机和 Raspberry Pi 上进行推理。 在本节中,我们将使用 tflite 模型并在 iPhone 上执行推理。 iPhone 或 iPad 上的对象检测可以遵循两种不同的路径,如以下小节所述。
在本节中,我们将描述如何在 iPhone 上使用 tflite 模型进行对象检测。 有关详细信息,请参阅以下 GitHub 页面上概述的步骤。
本质上,该过程可以分为以下步骤:
run xcode-select --install
)。 请注意,即使您已经安装了 Xcode,也需要完成此步骤。git clone
https://github.com/tensorflow/examples.git
。$sudo gem install cocoapods
来安装cocoapods
。examples-master
或examples
。 相应地更改以下文件夹地址。$cd examples-master/lite/examples/object_detection/ios
$pod install
ObjectDetection.xcworkspace
的文件ObjectDetection
文件以下屏幕截图显示了在 pod 安装过程中您将在终端中看到的注解:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cMdbINQu-1681784662642)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/adf11341-f850-4b43-a95a-f7e54b7ce588.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ipjCfFni-1681784662642)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/2656ddf2-bd05-41dc-9d0b-66ffe9300a5a.png)]
前面的屏幕快照中描述的更改说明了如何用您的更改替换基线detect.tflite
和labelmap.txt
文件。 请注意,如果您不进行任何更改,而是通过将手机连接到 macOS 来运行 Xcode,则它将显示一个常规检测器,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-psdOCr0e-1681784662643)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/a50bc42d-3a36-4c41-a6b6-6ad55a96cc2c.png)]
要更改您的特定模型,请右键单击以删除旧模型,然后通过拖放安装新模型。 对代码内的文件名进行必要的更改,如“步骤 4”中所示。 以下屏幕截图显示了您将看到的输出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mV00ejfG-1681784662643)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/364bb991-2fdb-4ba9-9877-5b59a39d0714.png)]
即使图像已旋转,前面的屏幕截图也清楚地显示出很好的检测效果。
Core ML 是 Apple 的机器学习框架,该框架集成了来自 TensorFlow 等各种来源的神经网络模型,并在必要时进行了转换,然后优化了 GPU/CPU 性能以进行设备上的训练和推理,同时最大程度地减小了应用尺寸和功耗。 在 WWDC 2019 中引入的 Core ML 3 更新了设备上特定用户数据的神经网络模型,从而消除了设备到云的交互并最大程度地提高了用户隐私。 有关更多信息,请访问这里。 Core ML 本身建立在诸如 Accelerate 和 BNNS 以及 Metal Performance Shaders 之类的低级基元之上。 所有 Core ML 模型均具有.mlmodel
扩展名。
Core ML 的核心部分是 Create ML,它是用于图像分类和对象检测的 Apple 机器学习框架。 该系统类似于 TensorFlow,但使用零编码生成模型更容易。 在 macOS 上,打开 Xcode 并输入.mlmodel
,如以下屏幕截图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xVezoIcL-1681784662643)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/6612fd63-f175-4a05-950b-6c9880a8387c.png)]
现在,Create ML 中的整个模型开发过程仅涉及三个步骤:
以下屏幕截图显示了“创建 ML”中的训练过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uipAowNB-1681784662643)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/157a82ce-0a7f-4cab-a372-d87cb608f1b5.png)]
有关上述屏幕截图的一些关键要点如下:
开发模型后,将其移植到以下用 Swift 编写的视觉框架。 它将检测带有边界框的对象。
以下是有关应用开发的一些注意事项:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yTkQDwzL-1681784662643)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/3d776c62-9329-4302-9faa-20f56dffad73.png)]
ViewController.swift
,并将默认模型名称重命名为您的模型名称,如上图右侧所示。 最后,建立模型并在 iPhone 上运行。以下屏幕截图显示了模型输出。 它显示了我们使用 Create ML 开发的模型与我们使用 TensorFlow 开发并转换为.tflite
形式的模型提供的检测结果的比较:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lJ6QyFKb-1681784662644)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/a67c4a1b-181e-4def-942f-cbf53fa7f94f.png)]
转换器仅转换 TensorFlow 模型的一部分。 完整的 MobileNet-SSD TF 模型包含四个子图:Preprocessor
,FeatureExtractor
,MultipleGridAnchorGenerator
和Postprocessor
。 Core ML 工具仅转换模型中的FeatureExtractor
子图; 其他任务必须由开发人员自行转换。
图像标注是对象检测或分割的核心部分。 就神经网络开发中的手动工作而言,此部分最繁琐。 先前,我们描述了用于标注的三个工具:LebelImg
,VGG Image Annotator
和RectLabel
。 但是,还有许多其他工具可用,例如 Supervisely 和 Labelbox。 其中一些工具会执行半自动标注。 最大的挑战是创建 100,000 个标注,并在像素级精度内正确地进行标注。 如果标注不正确,则开发的模型将不正确,并且在 100,000 张图像中找到不正确的标注就像在大海捞针中找针。 对于大型项目工作,标注工作流可以分为两类:
在下一节中,我们将讨论这两种方法。
许多企业将标签工作作为其核心业务模型之一。 每个云服务提供商都与人类标签商合作,为神经网络开发工作执行准确的图像标签服务。 以下是有关在哪里可以找到第三方数据标签服务的一些信息。 请注意,此列表并不全面,因此请在此列表之外进行自己的研究,以找到适合您需求的数据标签服务:
数据标记服务的成本可能会很高。
在本节中,我们将讨论一个完全免费的自动标注工具,该工具应减少人工标记的程度。 这是英特尔的计算机视觉标注工具(CVAT)工具,它非常有前途,仅通过加载模型即可执行完整的自动标注作为起点。 您可以在这个页面中找到有关该工具的更多信息。 。
该工具能够为边界框,多边形和语义分段创建标注,并且还可以执行自动标注。 该工具可以将标注输出为 VOC XML,JSON TXT 或 TFRecord 文件。 这意味着,如果您使用该工具,则无需将图像转换为 TFRecord 形式–您可以直接训练神经网络。 请按照以下步骤学习如何使用该工具:
localhost:8080
。 这将打开 CVAT。 请注意,CVAT 当前仅可在 Google Chrome 浏览器上使用。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfTatTT0-1681784662644)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/e1fb61bb-7fa6-41d3-ad83-b03c9723a6e1.png)]
对于 TensorFlow,只有一种模型可供选择。 但是,您仍然需要从下拉列表中选择类,如前面的屏幕快照所示。 请注意,您可以选择多个类别,但不会显示选定的类别。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9AgA9JNS-1681784662644)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/80fc9121-fc2a-4d57-8659-2dc90d4c28e8.png)]
如前面的屏幕快照所示,已上传了九张图像。 然后,单击“提交”按钮,这将创建任务。 您可以将不同的人分配给不同的任务。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tw3lM5C6-1681784662644)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/cbcf29f5-1fe4-4588-952f-56e2e5b75956.png)]
在前面的示例中,我们一次批量加载了所有九个图像,以演示自动化过程的有效性。 它正确检测了所有物体(汽车,人,卡车和摩托车)。 在某些情况下,该模型没有绘制交通信号灯和停车标志。 因此,在此示例中,只有交通信号灯和停车标志需要手动标注; 我们可以将工具用于所有其他对象。 接下来,我们以 VOC XML 格式获取该工具的输出,并将图像以及.xml
文件加载到标签边界框的labelImg
工具中。 以下屏幕截图显示了结果。 请注意,这是上述屏幕快照的左下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-865cnxPA-1681784662645)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/94644d6e-9a04-4733-b4b8-7dc42b806a4e.png)]
数据显示贴标工作非常准确。 该工具不断更新。 与其他任何工具一样,如果遇到此处未涉及的任何问题,请提交工作单。
我发现了与该工具有关的一个问题:输出不一致表示对于某些图像,它将绘制边界框标注,而对于其他图像,则不会。 我通过移至另一台 Linux PC 并重新安装 CVAT 来解决了此问题。 要在当前 PC 上解决此问题,可以在当前 CVAT 目录中卸载 Docker,删除 CVAT 文件夹,并确保端口8080
没有被其他程序调用。 然后,您可以重新安装 CVAT。
在本章中,您学习了如何在网络的最远端开发和优化卷积神经网络模型。 神经网络的核心是需要训练的大量数据,但最终,它提供了一个模型,该模型无需人工干预即可完成任务。 在前面的章节中,我们了解了必要的理论和实现的模型,但从未进行任何实际练习。 在实践中,摄像机可以用于监视,监视机器性能或评估手术过程。 在每种情况下,嵌入式视觉都用于实时设备上数据处理,这需要在边缘设备上部署更小,更有效的模型。
在本章中,您了解了各种单板计算机和加速器的性能,从而使您能够针对特定应用选择哪种设备做出明智的决定。 然后,我们学习了如何使用 OpenVINO 工具包和 TensorFlow Lite 来设置 Raspberry Pi 并在其上部署神经网络。 我们这样做是为了进行设备上的推断。 之后,我们学习了如何将 TensorFlow 模型转换为 TensorFlow Lite 模型并将其部署在 Android 和 iOS 设备上。 我们还了解了 Apple 的 Core ML 平台,并使用 Create ML 训练神经网络以开发对象检测器模型。 然后,我们将其与 TensorFlow Lite 对象检测器模型进行了比较。 我们在本章结束时概述了图像标注和自动标注方法。
在下一章中,我们将学习如何使用云处理来训练神经网络,然后将其部署在设备上。
云计算使用互联网从远程硬件普遍访问数据。 此类数据存储是使用云平台完成的。 对于计算机视觉,数据主要是图像,标注文件和结果模型。 云平台不仅存储数据,而且还执行训练,部署和分析。 云计算与边缘计算的不同之处在于,我们无需在基础设施上进行投资,就可拥有几乎瞬时的分析速度。
在本章中,您将学习如何在 Google Cloud Platform(GCP), Amazon Web Services(AWS)和 Microsoft Azure 云平台中打包应用以进行训练和部署。 您将学习如何准备数据,上传到云数据存储以及如何监视训练。 您还将学习如何将图像或图像向量发送到云平台进行分析并获得 JSON 响应。 本章讨论单个应用以及如何在计算引擎上运行分布式 TensorFlow。 训练结束后,本章将讨论如何评估模型并将其集成到应用中以进行大规模操作。
本章分为以下几节:
在前两章中,我们学习了如何设置 Google Colab 以使用 SSD,R-CNN 和 R-FCN 以及 Inception 和 MobileNet 作为骨干预训练网络来训练自定义对象检测器。 我们的网络用于检测汉堡和薯条。 在本节中,我们将学习如何使用 GCP 执行相同的任务。 您也可以在这里。
我从上一篇文章开始,但是发现必须精简许多部分,并且需要添加其他详细信息才能使其在我的 Ubuntu PC 上运行。 以下小节提供了使用 GCP 训练目标探测器的分步过程。
请注意,本节涉及许多将本地终端连接到 GCP 的大步骤,有时信息流可能会造成混乱。建议您在本节开始之前仔细阅读本节结尾处提供的流程图。 在 AWS Sagemaker 云平台上训练对象检测器,以了解一般的信息流。
在本节中,将在 GCP 中创建一个项目。 一个项目包括账单,数据存储,API,认证和团队成员信息,以开始您的训练工作。 GCP 是 Google 的机器学习平台,用于存储,构建,训练和部署模型。 通过转到这里登录到 GCP 控制台。
首先,使用您的 Gmail ID 和密码登录,您将看到以下控制台:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHgep4kW-1681784662645)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/e8a37646-4f8b-4083-b963-59c1bc6ce5a4.png)]
进入控制台后,请花一些时间来熟悉各种选项。 特别是,您必须填写有关帐单,API 和项目设置的信息。 以下小节概述了详细的说明。
转到这里设置 GCP 并使用您的 Gmail 帐户登录。 在上一节的屏幕快照中,有三个矩形框,它们是您需要设置的三个主要部分。 步骤概述如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2dlZt6CS-1681784662645)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/de81e552-ecaf-4070-8cbd-63f8c8b1072c.png)]
存储桶是保存数据的容器。 所有云服务提供商都有存储桶。 存储桶的格式与 PC 的目录结构相同。 存储桶可以包含图像(.jpg
文件),标注,TFRecord,检查点文件和模型输出。 在本部分中,我们将学习如何安装 Google Cloud Storage(GCS)存储桶以存储训练和测试数据。
要使用 GCP API 设置存储桶,请按照以下步骤操作:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aUN5tiuw-1681784662645)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/aace5356-40d0-4073-876f-b3e7d9dcc187.png)]
data
的文件夹,然后将文件上传到其中。 请看以下屏幕截图,了解如何执行此操作:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QXllbR9T-1681784662646)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/0ac81fac-f1a8-4470-bd25-2834d6b1c56e.png)]
如前面的屏幕快照所示,首先创建一个名为data
的文件夹。 然后,单击“数据”,单击“上载文件”,然后上载test.record
,train.record
,label_map.pbtxt
,pipeline.config
和model.ckpt*
(三个文件)。 我们将在下一节中介绍如何获取这些文件。
此过程涉及到设置 Google Cloud SDK,然后将 Google Cloud 项目和存储桶链接到您的终端,以便您可以在那里上传文件。 请记住,训练将由终端命令启动,因此,即使您使用前面的 API 进行了设置,您仍然需要执行以下部分中显示的步骤(从“开始设置 Google Cloud SDK”部分)以将终端链接到 GCP。
Google Cloud SDK 是一组命令行工具,使您的 PC 可以与 Google Cloud 进行交互。 由于在本节中,我们将使用 Ubuntu 终端与 Google Cloud 进行交互,因此我们需要首先设置 SDK。 在终端中输入以下命令:
$ echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
$ curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
$ sudo apt-get update && sudo apt-get install google-cloud-sdk
$ gcloud init
在前面的代码的前三行中,我们获得了 SDK 列表,然后使用apt-key
对包进行认证,然后安装 SDK。 在第四行中,我们将使用gcloud.init
设置gcloud
配置。
同样,如前所述,如果您在遵循本节时遇到任何困难,可以查看本节末尾提供的流程图,以了解一般的信息流。
接下来,我们将您的本地 PC 链接到 Google Cloud 项目。
在上一节的步骤中,我们设置了 Google Cloud SDK。 现在,我们需要执行最重要的步骤,这是将 Ubuntu 终端接到 Google Cloud 项目以及您之前创建的存储桶。
为什么需要将 Ubuntu 终端链接到 Google Cloud 项目? 答案是我们使用本地 PC 上的终端启动训练命令,但是我们的数据存储在 GCP 的存储桶中,并且模型将在 GCP 中生成。 因此,我们需要将 PC 终端连接到 GCP 以完成训练任务。
在终端中按顺序输入以下步骤:
rcnn-trainingpack
:$ gcloud config set project rcnn-trainingpack
gsutil
Python 命令,如下所示:$ gsutil mb gs://krish_burgerfries
$ export PROJECT="rcnn-trainingpack"
$ export YOUR_GCS_BUCKET="krish_burgerfries"
张量处理单元(TPU)是 Google 开发的一种 AI 加速器,用于快速处理大量数据以训练神经网络。
$ curl -H "Authorization: Bearer $(gcloud auth print-access-token)"
https://ml.googleapis.com/v1/projects/${PROJECT}:getConfig
前面的命令会将以下输出返回到“终端”窗口。 请注意,服务名称和项目名称将与您的应用不同:
{"serviceAccount": "service-444444444444@cloud-ml.google.com.iam.gserviceaccount.com",
"serviceAccountProject": "111111111111",
"config": {"tpuServiceAccount": "service-111111111111@cloud-tpu.iam.gserviceaccount.com" }}
{"serviceAccount": "service-444444444444@cloud-ml.google.com.iam.gserviceaccount.com",
"serviceAccountProject": "111111111111",
"config": {
"tpuServiceAccount": "service-111111111111@cloud-tpu.iam.gserviceaccount.com" }}
tpuServiceAccount
路径,将 TPU 帐户导出为环境变量,如下所示:$ export TPU_ACCOUNT="service-111111111111@cloud-tpu.iam.gserviceaccount.com"
ml.serviceAgent
角色授予 TPU 帐户:$ gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$TPU_ACCOUNT --role roles/ml.serviceAgent
这将在终端中产生一系列注解,从Updated IAM policy for the project [rcnn-trainingpack]
开始。
现在我们已经将终端链接到存储桶和 Google Cloud 项目,下一步是将其链接到 TensorFlow 对象检测 API。 请遵循这里提供的一组说明。
前面的安装链接包含许多未在此处列出的代码行。 您将能够正确执行大多数代码。 此过程的最后两行代码描述如下:
# From tensorflow/models/research/
export PYTHONPATH=$PYTHONPATH:'pwd':'pwd'/slim
python object_detection/builders/model_builder_test.py
该说明说,前面的步骤对于成功安装至关重要。 但是,如果您的 PC 上安装了 TensorFlow 2.0,则可能会出现以下错误:
AttributeError: module 'tensorflow' has no attribute 'contrib'
即使此错误已解决,也会导致另一个与 TensorFlow 2.0 与 TensorFlow 对象检测 API 不兼容有关的错误。 因此,我们将改为描述替代路径。 另一种选择是使用这里,类似于我们在第 10 章“使用 R-CNN,SSD 和 R-FCN 进行对象检测”,和第 11 章“在具有 CPU/GPU 优化功能的边缘设备上进行深度学习”中使用 TensorFlow 1.15 在 Google Colab 中运行它。
如“使用 GCP API”部分设置存储桶中所述,我们需要填充以下bucket: test.record
,train.record
,label_map.pbtxt
,pipeline.config
和model.ckpt*
(三个文件 )。 在下面的小节中,我们将说明如何填充这些内容。
TFRecord 文件是高效的 TensorFlow 文件格式,用于以单一二进制格式存储图像和标注文件,以供 TensorFlow 模型超快速读取。 TFRecord 已在“第 10 章”,“使用 R-CNN,SSD 和 R-FCN”的对象检测中引入。 在本节中,我们将描述如何准备数据然后上传。
首先,从“第 10 章”,“使用 R-CNN,SSD 和 R-FCN 进行对象检测”,和“第 11 章”,“通过 CPU/GPU 优化在边缘设备上进行深度学习”的 Google Colab 项目中复制 TFRecord 文件(即train.record
和test.record
),并将其放入 PC 上的目录中。 同样,将label_map.pbtxt
复制到同一目录中的pbtxt
文件中。
在这里,我们将看一下使用终端的数据上传方法:
train.record
上传到 GCP。 这将使用gsutil
Python 命令将文件从本地目录复制到 GCS 存储桶。 确保还包括该子目录。 例如,在这种情况下,YOUR_GCS_BUCKET
将是您的存储桶的名称; 如果为burgerfries
,则命令将为$burgerfries/data
,其中data
是burgerfries
下的子目录,文件存储在其中:$ gsutil -m cp -r /Documents/chapter12_cloud_computing/burgerfries/annotation/train.record gs://${YOUR_GCS_BUCKET}/data/
Copying file:///Documents/chapter12_cloud_computing/burgerfries/annotation/train.record [Content-Type=application/octet-stream]...
\ [1/1 files][ 2.6 MiB/ 2.6 MiB] 100% Done
test.record
上传到 GCP:$ gsutil -m cp -r /Documents/chapter12_cloud_computing/burgerfries/annotation/test.record gs://${YOUR_GCS_BUCKET}/data/
Copying file:///Documents/chapter12_cloud_computing/burgerfries/annotation/test.record [Content-Type=application/octet-stream]...
\ [1/1 files][ 1.1 MiB/ 1.1 MiB] 100% Done
Operation completed over 1 objects/1.1 MiB.
label_map.pbtxt
上传到 GCP:$ gsutil -m cp -r /Documents/chapter12_cloud_computing/burgerfries/annotation/label_map.pbtxt gs://${YOUR_GCS_BUCKET}/data/
Copying file:///Documents/chapter12_cloud_computing/burgerfries/annotation/label_map.pbtxt [Content-Type=application/octet-stream]...
/ [1/1 files][ 75.0 B/ 75.0 B] 100% Done
Operation completed over 1 objects/75.0 B.
如果您不使用终端,则只需使用 Google Cloud 存储桶中的 Upload 命令上传文件,如“使用 GCP API”部分的屏幕截图所示。
model.ckpt
文件在本节中,我们将学习如何下载预训练模型的检查点文件。 检查点是模型的权重。 这些权重将被上传到 GCS 存储桶,以使用迁移学习来开始训练:
model.tar
文件。
ssd_mobilenet_v1_0.75_depth_300x300_coco14_sync_2018_07_03.tar.gz
检查点捕获模型使用的所有参数的确切值。 解压缩文件时,您会注意到文件类型如下:
model.ckpt.data-00000-of-00001
:一个二进制数据文件,其中包含训练变量权重,梯度等的值model.ckpt.index
:描述每个检查点的索引值的二进制文件model.ckpt.meta
:描述保存的图结构; 它是一个协议缓冲区Checkpoint
:记录最新的检查点文件模型config
文件是一个文本文件,定义了模型的以下重要特征:
map.pbtxt
的位置在训练期间,模型使用config
文件输入和设置参数。 您可以在 TensorFlow 目录中的以下路径下找到config
文件的列表:
models-master/research/object-detection/samples/configs
请注意,在撰写本文时,仅在 TensorFlow 1.x 中提供了先前的目录,而在 2.x 中则没有。 因此,如果您的 PC 上安装了 TensorFlow 2.0,请使用下面讨论的替代步骤来获取config
文件。
或者,您可以转到这里,然后在文本编辑器中复制config
文件。 也可以从前面的链接下载相应的.config
文件。
以下列表显示了config
文件中需要进行的更改:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8b4ZlGUO-1681784662646)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/0dc98ffc-6a1c-4f80-b1f8-22e5f52388e3.png)]
在前面的列表中,所有更改都用矩形标记。 左侧列表显示原始config
文件,右侧列表显示更改的config
文件。 这里,假设TFRecord
文件名是train.record
和test.record
,pbtxt
文件名是label_map.pbtxt
,并且 Google 存储驱动器中的路径是krish_burgerfries/data
。 如果文件名或路径不同,则可以进行相应更改。
现在,通过在终端中键入以下命令转到 TensorFlow research
目录:
$cd models-master/research
有关包对象检测 API,pycocotools
和tf-slim
的信息,请参见以下命令:
models-master/research$ bash object_detection/dataset_tools/create_pycocotools_package.sh /tmp/pycocotools
models-master/research$ python setup.py sdist
models-master/research$ (cd slim && python setup.py sdist)
完成上述所有步骤后,我们将准备进行训练。 如前所述,通过执行以下命令在终端中开始训练:
{YOUR_GCS_BUCKET}
更改为burgerfries
(在您的情况下,如果名称不同,则将其更改为该名称)。 完成后,将其粘贴到终端中并点击Enter
:$ gcloud ml-engine jobs submit training `whoami`_object_detection_`date +%s` --job-dir=gs://${YOUR_GCS_BUCKET}/train --packages dist/object_detection-0.1.tar.gz,slim/dist/slim-0.1.tar.gz,/tmp/pycocotools/pycocotools-2.0.tar.gz --module-name object_detection.model_tpu_main --runtime-version 1.15 --scale-tier BASIC_TPU --region us-central1 -- --model_dir=gs://${YOUR_GCS_BUCKET}/train --tpu_zone us-central1 --pipeline_config_path=gs://${YOUR_GCS_BUCKET}/data/pipeline.config
{YOUR_GCS_BUCKET}
更改为burgerfries
(在您的情况下,如果名称不同,则将其更改为该名称)。 完成此操作后,将其粘贴到终端中,然后单击Enter
:$ gcloud ml-engine jobs submit training `whoami`_object_detection_eval_validation_`date +%s` --job-dir=gs://${YOUR_GCS_BUCKET}/train --packages dist/object_detection-0.1.tar.gz,slim/dist/slim-0.1.tar.gz,/tmp/pycocotools/pycocotools-2.0.tar.gz --module-name object_detection.model_main --runtime-version 1.15 --scale-tier BASIC_GPU --region us-central1 -- --model_dir=gs://${YOUR_GCS_BUCKET}/train --pipeline_config_path=gs://${YOUR_GCS_BUCKET}/data/pipeline.config --checkpoint_dir=gs://${YOUR_GCS_BUCKET}/train
$ gcloud ai-platform jobs describe krishkar_object_detection_1111111111
在此,末尾的数字对于您的应用将有所不同,并将在终端中显示出来。 键入前面的命令后,您可以在这个页面中检查训练作业。
请注意,URL 的xxxxx
和1111111111
部分只是示例; 您的值将有所不同,并会在终端中显示出来。
在“第 10 章”,“使用 R-CNN,SSD 和 R-FCN”进行对象检测中,我们学习了如何使用 Google Colab 在 TensorBoard 中查看 TensorFlow 模型输出结果。 在本节中,我们将向您展示如何通过在终端中执行命令从云平台启动 TensorBoard:
tensorboard --logdir=gs://${YOUR_GCS_BUCKET}/train
运行上述命令后,如果遇到错误,例如ValueError: Duplicate plugins for name projector
,则从这里并将其保存到您的目录中。
diagnose_tensorboard.py
的安装目录并执行以下命令:$ python diagnose_tensorboard.py
它将运行并提供可能的修复建议。 就我而言,它要求以下修复:
### Suggestion: Fix conflicting installations
"Conflicting package installations found. Depending on the order of installations and uninstallations, behavior may be undefined. Please uninstall ALL versions of TensorFlow and TensorBoard, then reinstall ONLY the desired version of TensorFlow, which will transitively pull
in the proper version of TensorBoard. (If you use TensorBoard without TensorFlow, just reinstall the appropriate version of TensorBoard directly.)
Namely:
pip uninstall tb-nightly tensorboard tensorflow-estimator tensorflow-estimator-2.0-preview tensorflow-gpu tf-nightly-gpu-2.0-preview
pip install tensorflow # or `tensorflow-gpu`, or `tf-nightly`, ..."
localhost:6006
以查看 TensorBoard 结果。在 TensorBoard 中,您将看到所用神经网络的图以及在测试图像上显示边界框的图像。 请注意,在 TensorFlow 中,我们没有上传图像,但是它是从TFRecord
文件获取图像的。 TensorBoard 还显示准确率和精度数据,如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V8KG4dPK-1681784662646)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/1299acd6-8cd6-4a62-962a-73b8b3b0fcfd.png)]
精度数据不高,但可以通过添加更多图像来改进-在我们的示例示例中,我们仅使用 68 张图像进行训练。
现在我们已经创建了模型并观察了其输出,在下一部分中,我们将描述如何打包模型,以便您可以将其部署在边缘设备(例如手机)上以进行实时显示。 在此处打包模型意味着冻结模型,这意味着该模型不再受训练。
到目前为止,我们已经学习了如何将 TFRecord 格式的图像上传到 GCP,然后使用 SSD MobileNet 模型来训练针对汉堡和薯条的自定义模型。 在本节中,我们将回顾模型输出的组成部分,并学习如何冻结模型。 冻结模型涉及以某种格式保存 TensorFlow 图和权重,以后可用于推断。 模型输出存储在train
文件夹中,并且包含以下文件:
graph.pbtxt
:这是一个文本文件,描述了 TensorFlow 图上每个节点的值,列表和形状model.ckpt-xxxx.data-00000-of-00001
:这是一个二进制文件,指示所有变量文件的值model.ckpt-xxxx.index
:这是一个代表表的二进制文件,其中每个键是张量的名称及其值model.ckpt-xxxx.meta
:这描述了保存的图结构train_pipeline.config
:此文本文件描述了模型参数-在模型配置文件的前两个部分中也有说明请注意,在前面的步骤中,我仅以xxxx
为例。 您的值将有所不同。 输入该信息而不是xxxx
。
抓取最新的数据文件(单击鼠标右键并下载),因此,在本示例中,抓取包含-2000
的文件。
下一个任务是将检查点输出转换为冻结的推理图。 下节介绍了三种方法:
freeze_graph.py
: $ python freeze_graph.py --input_graph=train_graph.pbtxt -- input_checkpoint=train_model.ckpt-2000 -- output_graph=frozen_graph.pb --output_node_name=softmax
freeze_graph
: import tensorflow as tf
from tensorflow.python.tools import freeze_graph
checkpoint_path = './'+'train_model'+'.ckpt-2000'
freeze_graph.freeze_graph('train_graph.pbtxt', "", False, checkpoint_path, "output/softmax", "save/restore_all", "save/Const:0",'frozentensorflowModel.pb', True, "")
对于上述两种方法,我们都会得到两种类型的错误:
IndexError: tuple index out of range
AttributeError: module 'tensorflow_core.python.pywrap_tensorflow' has no attribute 'NewCheckpointReader'
tflite graph.py
上执行export
函数,然后下载相关文件: $export CONFIG_FILE=gs://${YOUR_GCS_BUCKET}/data/pipeline.config
$export CHECKPOINT_PATH=gs://${YOUR_GCS_BUCKET}/train/model.ckpt-2000
$export OUTPUT_DIR=/tmp/tflite
Docker 是一种虚拟机,使开发人员可以将应用及其所有组件打包在一起。 对于 TensorFlow,使用 Docker 的优势是将 TensorFlow 安装与 PC 操作系统隔离。 这种隔离消除了我们之前观察到的许多与 TensorFlow 相关的错误:
$python object_detection/export_tflite_ssd_graph.py \
--pipeline_config_path=$CONFIG_FILE \
--trained_checkpoint_prefix=$CHECKPOINT_PATH \
--output_directory=$OUTPUT_DIR \
--add_postprocessing_op=true
在以下部分中,我们将描述“第 11 章”,“在具有 CPU/GPU 优化功能的边缘设备上进行深度学习”提及的tflite
转换过程。
graph.py
在“第 10 章”,“使用 R-CNN,SSD 和 R-FCN 的对象检测”和“第 11 章”,“在具有 CPU/GPU 优化的边缘设备上进行深度学习”,我们使用 Google Colab 将检查点转换为冻结图。 我们将在此处使用相同的方法,除了我们将导入配置,检查点和输出目录,如下所示:
CONFIG_FILE = '/content/sample_data/train_pipeline.config'
CHECKPOINT_PATH = '/content/sample_data/train_model.ckpt-2000'
OUTPUT_DIR = '/content/sample_data'
将文件上传到 Google 云端硬盘,然后将其拖到 Google Colab 中名为sample_data
的文件夹中。 您可以创建一个不同的名称来代替sample_data
。 之后,执行以下代码:
请注意,如果您没有通过将文件拖到 Google Colab 中来携带文件,而是将 Google Colab 链接到文件所在的 Google 云端硬盘,则可能会产生错误,因为在此期间无法找到文件来执行。
import re
import numpy as np
!python /content/models/research/object_detection/export_tflite_ssd_graph.py \
--input_type=image_tensor \
--pipeline_config_path={CONFIG_FILE} \
--output_directory={OUTPUT_DIR} \
--trained_checkpoint_prefix={CHECKPOINT_PATH} \
--add_postprocessing_op=true
因此,总而言之,下图表示在 GCP 上训练自定义对象检测器的流程图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YrJbWqvp-1681784662646)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/771c10ac-1d93-40f9-947b-66b2d1e90f73.png)]
首先创建一个项目,然后创建账单,设置 API 和存储桶,准备 TensorFlow 对象检测 API,准备和上传数据集,然后开始训练。 虚线矩形内的两个圆角矩形表示完成同一任务的两种不同方法。 训练完成后,涉及的步骤包括生成冻结图,转换tflite
表单并部署到移动设备。 部署到移动设备的过程与“第 11 章”,“具有 CPU/GPU 优化功能的边缘设备上的深度学习”中的方法相同,因此在此不进行描述。
AWS 是用于在云中执行各种任务的 Amazon 云平台。 AWS SageMaker 是机器学习平台,用于使用 AWS 交互式平台训练和部署模型。 AWS SageMaker 与 AWS S3 存储桶进行交互以存储和检索数据。 下一节将介绍训练对象检测器的分步过程。
通过与 AWS 支持联系,将服务限制增加到ml.p3.2xlarge
或类似的值。 请注意,实例类型最多可能需要两个工作日才能获得批准,因此请进行相应的计划。 如果不这样做,则会出现以下错误:
ResourceLimitExceeded
用于训练作业使用情况的帐户级别服务限制ml.p3.2xlarge
为零实例,当前利用率为零实例,请求增量为一个实例。 请联系 AWS 支持以请求增加此限制。
.xml
文件转换为 JSON 格式AWS SageMaker 标注数据使用 JSON 格式而不是我们之前使用的.xml
。 通过以下步骤将.xml
文件转换为 COCO JSON 格式:
voc2coco.py
Python 文件所在的目录。
trainxml
的目录,其中包含所有.xml
文件。 该目录应与voc2coco.py
位于相同的主目录中。
trainlist.txt
的文件,该文件应列出所有.xml
文件名。 您可以在终端中复制此文件,然后将所有.xml
文件复制并粘贴到文本文件中以创建此类文件。
classname.txt
文件,该文件应列出training
文件夹中的所有类。 在此示例中,它将有两行-burger
和fries
。
$ python voc2coco.py --ann_dir trainxml --ann_ids trainlist.txt --labels classname.txt --output train_cocoformat.json
最终输出是cocoformat.JSON
文件,它是所有.xml
文件的一个组合 JSON 文件。
COCO JSON
文件转换为单个 JSON 文件。Chapter12_cocojson_AWSJSON_train.ipynb
Jupyter 笔记本将COCO JSON
文件转换为单个 JSON 文件。 可以在这个页面上找到此文件。 这是对 Amazon 提供的对象检测代码的修改。 此代码不是从 GitHub 页面获取COCO JSON
文件,而是从本地驱动器获取上一步中创建的cocoformat.JSON
文件,然后将其转换为生成的文件夹中的多个.JSON
文件。S3 存储桶是用于在 AWS 中存储数据的云存储容器。 本节介绍如何将数据从我们的 PC 上传到 S3 存储桶:
train_channel
:train
图片.jpg
文件train_annotation_channel
:train
标注.JSON
文件。 每个文件对应于每个train
图像。validation_channel
:validation
图片.jpg
文件validation_annotation_channel
:validation
标注.JSON
文件。 每个文件对应于每个validation
图像。让我们按照以下步骤操作:
ml.p2.nxlarge
,其中n
可以为 1、2、8,依此类推)。 请注意,如果实例类型是标准类型(例如ml.m5.nxlarge
)或计算优化型(例如ml.c5.nxlarge
),则训练将失败。 因此,如前所述,请求增加服务限制。sample1
是 S3 存储桶名称,DEMO
是其中包含sample1
的文件夹,其中有六个文件夹-两个数据文件夹,其中包括.jpg
图像,两个标注文件夹由.json
文件,输出和检查点文件组成。 请注意,路径必须正确; 否则,可能会产生错误:s3://sample1/DEMO/s3_train_data/
s3:// sample1/DEMO/s3_train_annotation/
s3:// sample1/DEMO/s3_validation_data/
s3:// sample1/DEMO/s3_validation_annotation/
s3:// sample1/DEMO/s3_checkpoint/
s3:// sample1/DEMO/s3_output_location/
s3_output_location
中,作为model.tar.gz
文件。 检查点将存储在前面代码中定义的s3_checkpoint
位置。以下是一些在训练过程中失败的原因及其解决方法:
s3://DEMO-ObjectDetection/s3_train_data/
S3 URL 上找不到 S3 对象。 请确保存储桶位于所选区域(us-east-1
)中,对象存在于该 S3 前缀下,并且arn:aws:iam::11111111:role/service-role/AmazonSageMaker-ExecutionRole-xxxxxxx
角色对DEMO-ObjectDetection
存储桶具有s3:ListBucket
权限。 或者,来自 S3 的The specified bucket does not exist
错误消息。 解决方案:更改 S3 存储桶路径,如前所述。 对train
,validation
,annotation
和image
数据文件各重复一个。
ClientError
:validation
集没有足够的带标注文件。 请确保带有有效标注的文件数量大于mini_batch_size
,并且实例中的 GPU 数量更大。 解决方案:要记住的重要一点是批量大小必须小于validation
文件的数量。 因此,如果validation
文件的数量为 32,批量大小为 32,则将微型批量大小从 32 更改为 12,以解决此错误。
ClientError
:无法初始化算法。 train_annotation
通道的ContentType
为空。 请为train_annotation
频道设置内容类型(由KeyError
引起)。 由u'train_annotation'
引起。 解决方案:确保内容类型不为空白。 将内容类型更改为application/x-image
。
ClientError
:无法初始化算法。 无法验证输入数据配置(由ValidationError
引起)。 由u'train'
引起的是必需属性。 无法验证架构中的u'required'
:{u'$schema'
:u'http://json-schema.org/draft-04/schema#', u'additionalProperties':
False
,u'definitions': {u'data_channel': {u'properties': {u'ContentType': {u'type': u'string'}
,u'RecordWrapperType': {u'enum': [u'None', u'RecordIO'], u'type': u'string'}, u'S3DistributionType': {u'enum': [u'FullyReplicated', u'ShardedByS3Key'], u'type': u'string'}
。 解决方案:AWS 希望通道名称为train_validation
,train_annotation
和validation_annotation
。 如果您附加了_channel
(train_channel
,validation_channel
,train_annotation_channel
和validation_annotation_channel
),则将导致错误。 因此,要解决此问题,请从文件名中删除_channel
。
如果在此过程中遇到问题,请通过创建故障单来联系 AWS 支持人员。 解决所有错误后,成功的训练将具有以下参数:
base_network
是resnet-50
early_stopping
是false
early_stopping_min_epochs
是10
early_stopping_patience
是5
early_stopping_tolerance
是0.0
epochs
是30
freeze_layer_pattern
是false
image_shape
是300
label_width
是350
learning_rate
是0.001
lr_scheduler_factor
是0.1
mini_batch_size
是12
momentum
是0.9
nms_threshold
是0.45
num_classes
是2
num_training_samples
是68
optimizer
是sgd
overlap_threshold
是0.5
use_pretrained_model
是1
weight_decay
是0.0005
请注意,训练的输出将与检查点一起保存在 S3 输出位置。
完成上述练习后,您将熟悉在 GCP 和 AWS 中训练神经网络模型。 接下来,我们将使用 Microsoft Azure 云平台进行训练。
在本节中,我们将使用 Azure 自定义视觉来训练对象检测器。 可以在这个页面中找到有关使用 Microsoft Azure 云平台训练对象检测器的详细说明:。
下一节将详细介绍训练对象检测器时的各种过程。
在本节中,我们将设置一个 Azure 帐户和一个 Azure Custom Vision 平台。 以下步骤将帮助您配置 Azure 帐户并注册 Custom Vision 平台。 如针对 GCP 所述,此过程对于任何云平台都是相同的-设置帐单信息并设置项目-如以下屏幕快照所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RvNSTbT4-1681784662646)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/18daf432-57e5-48ea-9197-7a17a673a4b8.png)]
设置训练的具体步骤如下:
设置帐户设置是非常重要的部分,如果操作不正确,将花费相当长的时间。 设置帐户后,接下来的步骤实际上将很快进行。
在本节中,我们将训练图像上传到 Azure Custom Vision 平台。 按着这些次序:
train
和validation
图像。
.xml
或.JSON
文件,但不要担心,Azure 使标记图像非常简单。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OiDeXjPe-1681784662647)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/43aff5f4-c9b9-4b3a-84e5-21ad7115bd41.png)]
训练完成后,您将能够看到表现指标。 请注意,在上述快速训练之后,您将能够看到此内容。 以下屏幕截图显示了针对新训练的模型的精度,召回率和 mAP 方面的表现参数:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BEWeFnji-1681784662647)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/08e3cdba-f27b-48a0-b2bc-a781720d41c9.png)]
请注意,随着模型看到的图像越来越多,上一个屏幕快照中显示的 Precision 值可能会降低。 因此,在 20 张图像上开发的模型比在 100 张图像上开发的模型具有更高的精度。 这是因为在 20 张图像上开发的模型具有较少的训练误差,但具有较高的测试误差(在test
图像中,无法识别汉堡-仅识别薯条)。 mAP 数是 11 个等距召回级别(0,0.1,…,1)上的平均平均精度。 mAP 值不受图像添加的影响。 Performance
参数显示burger
和fries
的值。
validation
图像并查看结果。 为此,请单击顶部的“预测”,然后插入validation
图像。 它将在类周围绘制一个边界框,如下所示:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Eza1NNI8-1681784662647)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/f4081282-39a6-4a90-9178-05b09c7064ed.png)]
TF
,则可以选择导出为 TensorFlow Lite 或 TensorFlow。 同样,如果您单击iOS
,则可以选择导出为 CoreML:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-liLKQpbF-1681784662647)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/1e616edb-4ec6-4f40-94ce-48dd5a30ed0e.png)]
上面的屏幕截图显示了 TensorFlow Lite 中可用的各种导出选项。
TensorFlow 有一个名为tf.distribute.Strategy
的 API,可在多个 GPU 之间分配训练。 在这个页面上详细介绍了针对 Google Cloud 的大规模训练。
使用tf.distribute.Strategy
API 涵盖了使用 TensorFlow 进行分布式训练。 使用此 API,可以使用多个 GPU 或 TPU 分发 TensorFlow 训练。 有关分布式训练的详细概述(包括示例),请访问这里。
也可以在云计算引擎中设置分布式训练。 为了启用此功能,请在 GCP 中启用 Cloud Shell。 在 TensorFlow 集群中,设置一个主服务器和多个工作程序的虚拟机实例,并在每个这些计算机上执行训练作业。 有关详细信息,您可以转到这里。
应用打包涉及将代码,TFRecord
文件和模型.confg
文件上传到 GCP,模型在训练期间可以访问。 在“在 GCP 中训练对象检测器”的部分中,我们通过使用gcloud
打包应用在 GCP 中进行了训练,如下所示:
$ gcloud ml-engine jobs submit training `whoami`_object_detection_`date +%s` --job-dir=gs://${YOUR_GCS_BUCKET}/train --packages dist/object_detection-0.1.tar.gz,slim/dist/slim-0.1.tar.gz,/tmp/pycocotools/pycocotools-2.0.tar.gz --module-name object_detection.model_tpu_main --runtime-version 1.15 --scale-tier BASIC_TPU --region us-central1 -- --model_dir=gs://${YOUR_GCS_BUCKET}/train --tpu_zone us-central1 --pipeline_config_path=gs://${YOUR_GCS_BUCKET}/data/pipeline.config
请注意,在前面的训练中,我们使用了gcloud ml-engine
,它可以让您管理 AI 平台作业和训练模型。 还有另一个名为gcloud ai-platform
的平台,也可以用来打包您的应用,如下所示:
gcloud ai-platform jobs submit training $JOB_NAME \
--staging-bucket $PACKAGE_STAGING_PATH \
--job-dir $JOB_DIR \
--package-path $TRAINER_PACKAGE_PATH \
--module-name $MAIN_TRAINER_MODULE \
--region $REGION \
-- \
--user_first_arg=first_arg_value \
--user_second_arg=second_arg_value
前面的代码的解释如下:
--staging-bucket
:这是暂存training
包的云存储路径--job-dir
:这是输出文件位置的云存储路径--package-path
:这指定应用目录的本地路径--module-name
:这指定应用模块的名称--job-dir
标志:这是作业目录在 “第 6 章”,“使用迁移学习的视觉搜索”中,我们学习了如何在本地 PC 上进行视觉搜索。 该方法使用通过神经网络(例如 VGG16 或 ResNet)传递图像,并通过删除最后一个全连接层然后将其与数据库中已知类别的其他图像进行比较以将其转换为图像向量,以找到最近的邻居。 匹配,然后显示结果。
在示例中,我们从 200 张图像开始,但是如果图像数量达到 100 万张并且必须从网页访问结果,则在本地存储图像将毫无意义。 在这些情况下,云存储是最佳的。 在那种情况下,我们可以将图像向量存储,而不是将图像存储在云中,然后在用户上传图像时,将图像转换为向量并将其发送到云中进行处理。 在云中,我们执行 K 近邻搜索以找到并显示最接近的匹配项。 使用 REST API 或消息队列遥测传输(MQTT)服务将图像向量上传到云中。 每个服务都有自己的安全性验证。
在这里,我们将讨论将图像发送到云服务并以 JSON 消息形式接收的基本编码基础架构:
api_host
是 Web 服务器地址。 headers
文件是操作参数,在这种情况下为图像。 image_url
是实际的图像位置:api_host = 'https://…/'
headers = {'Content-Type' : 'image/jpeg'}
image_url = 'http://image.url.com/sample.jpeg'
img_file = urllib2.urlopen(image_url)
response = requests.post(api_host, data=img_file.read(),
headers=headers, verify=False)
print(json.loads(response.text))
request.files.get
方法请求图像(图片),并且picture.save
用于保存图像:@app.route('/', methods=['POST'])
def index():
picture = request.files.get('file')
picture.save('path/to/save')
return 'ok', 200
前面的代码架构展示了 REST API 方法从云发送和接收图像的基础。 GCP,AWS 和 Azure 具有适当的 API,可以执行视觉搜索,面部识别和许多其他任务。 在以下部分中,将对此进行详细描述。 每个云平台都有自己的向云发送图像数据的方式,这可能彼此不同,但是基本原理与前一个相同。 云网页将以 JSON 格式包含具有可视搜索结果的图像信息,该图像信息可以使用云服务器 URL 和认证方法从本地 PC 访问。
在本节中,我们将讨论使用三种不同的云平台(GCP,AWS 和 Azure)的可视搜索任务。 我们已经在“第 6 章”,“使用迁移学习进行视觉搜索”中,其中我们学习了如何将图像向量与 PC 目录中的大量图像进行比较,来查找基于欧几里得距离的最接近的匹配。 在本部分中,您将学习如何使用 REST API 从 PC 上载图像到云,云搜索引擎将搜索最接近的图像并将其显示。 因此,所有繁重的工作将由云引擎来完成。
请注意,在本节中,介绍了视觉搜索的基本概念。 内容可以更深入,您可以从 GCP,AWS 或 Azure 获取云 API,并将其插入用 Python,C++ 或 JavaScript 编写的应用中,以调用云引擎并执行搜索。
GCP 具有视觉 API,可以执行基于云的图像信息,包括面部检测和图像内容分析。 有关更多详细信息,请访问这里。 在以下屏幕截图中查看为沙发上传的示例结果; 检测连同视觉上类似图像的几个示例一起进行:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iR4weSm3-1681784662647)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/5b0384ab-24ec-41f1-acbc-c5dc5d54730d.png)]
正如我们在“第 6 章”,“使用迁移学习进行视觉搜索”时一样,对于视觉上相似的图像,必须在图像类内进行搜索。 如果图像不是来自网络,则很可能会检测到不同类别的相似视觉图像,如此处的沙发示例所示。 但是,如果图像是从网上获取的,则匹配是精确的或非常接近的。
在上一节中,我们学习了如何使用 GCP 进行训练。 AutoML Vision 是轻松完成此任务的另一种方法。 有关详细的分步说明,请转到这里。
要进行视觉搜索,请转到这里。
当您尝试使用 Python 脚本中的 API 时,您将需要以下内容:
GOOGLE_APPLICATION_CREDENTIAL
:PC 中的关键路径PROJECT_ID
LOCATION_ID
request.json
,然后您将收到一个response.json
文件。AWS 有许多用于计算机视觉的工具。 其中,两个主要工具是 Amazon Rekognition 和 AWS SageMaker。访问 AWS 网站以获取更多满足您需求的工具。 AWS Rekognition 是用于图像和视频分析的基于云的软件即服务(SaaS)平台。 它具有许多功能,例如面部检测和分析,面部搜索和验证以及名人识别。 就像 Google Cloud Vision API 一样,您可以上传图像,它可以提供图像信息的详细信息,如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-76CguLCo-1681784662648)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/f1ec323c-a06f-49f0-8be7-fd520d866ed4.png)]
在前面的屏幕截图中,正确检测了沙发以及不同的类别以及边界框和图像信息的相应 JSON。 您还可以上传面部图像,它可以提供有关面部表情,年龄和性别的详细信息,以及两个角度不同的面部是否属于同一个人,如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Den1Kl8n-1681784662648)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/master-cv-tf-2x/img/e39e0b60-60d7-4f93-819b-290e1117ed5b.png)]
请注意,面部识别系统能够检测到属于同一个人的两张脸,无论有无太阳镜,它们都是从不同角度拍摄的。
AWS Rekognition 还可以使用boto
分析本地 PC 上的图像,如这里所述。
训练期间引入了 AWS SageMaker。 通过将图像转换为向量,它也可以用于执行视觉搜索。 有关详细练习,请参阅这个页面中描述的 Python 笔记本。
请注意,执行此操作的最佳方法是从 AWS SageMaker 笔记本实例运行此操作。 将此文件(在上一链接中列出)上载到 Jupyter 笔记本,然后选择 MXNet Python 包。 引用您的 S3 存储桶并执行单元。 分析代码并将其与我们在“第 6 章”,“使用迁移学习的视觉搜索”中学到的内容进行比较。 您将看到基本原理是相同的,只是分析是在云平台上完成的,因此它将具有在“第 6 章”,“使用迁移学习的视觉搜索”中不必处理的多个认证级别。
Azure 是 Microsoft 的云机器学习平台,用于构建,管理和部署应用。 与 GCP 和 AWS 一样,Azure 具有许多功能,但我们对计算机视觉工作感兴趣的功能是 Azure AI 和 Azure 机器学习。 在 AI 和机器学习中,与计算机视觉相关的应用是 Azure Bot 服务,Azure 认知搜索,Bing 图像搜索,Bing 视觉搜索和计算机视觉。 例如,如果要执行视觉搜索,请转到这里。
在 Azure 云平台中进行可视搜索的基本步骤如下:
test
图像的路径。request.post
的形式发送搜索请求:response = requests.post(BASE_URI, headers=HEADERS, files=file)
response.raise_for_status()
在前面的代码中,raise_for_status
方法表示如果请求不成功,则会引发异常,例如404 Client Error: NOT FOUND
。
注意-由于必须提供信用卡详细信息进行计费,因此云平台的使用可能会变得昂贵。 要注意的关键是,即使您完成了训练工作并关闭了 PC,除非完全关闭云平台中的项目,否则您将继续产生费用。
在本章中,您学习了如何将图像数据发送到云平台进行分析。 在之前的章节中,我们学习了如何在本地 PC 上进行训练,但是在本章中,您学习了如何使用云平台执行相同的任务,以及如何使用 Google Cloud Shell for distribution 在多个实例中触发训练。
本章包含许多示例和链接,通过查看这些链接并进行练习,您将获得更多知识。 然后,我们学习了如何将图像发送到云平台进行实例分析。 图像内容分析已扩展到可以在云平台中执行可视搜索。 我们还学习了如何使用所有三个云平台-GCP,AWS 和 Azure。 请记住,即使您尚未接受训练,也要确保在完成任务后关闭项目,以免产生不必要的费用。