关于人工智能:构建对象检测模型

3次阅读

共计 6114 个字符,预计需要花费 16 分钟才能阅读完成。

作者 |ALAKH SETHI
编译 |VK
起源 |Analytics Vidhya

指标检测

我喜爱深度学习。坦率地说,这是一个有大量技术和框架可供倾泻和学习的广大畛域。当我看到事实世界中的应用程序,如面部辨认和板球跟踪等时,建设深度学习和计算机视觉模型的真正兴奋就来了。

我最喜爱的计算机视觉和深刻学习的概念之一是指标检测。建设一个模型的能力,能够通过图像,通知我什么样的物体存在!

当人类看到一幅图像时,咱们在几秒钟内就能辨认出感兴趣的物体。机器不是这样的。因而,指标检测是一个在图像中定位指标实例的计算机视觉问题。

好消息是,对象检测应用程序比以往任何时候都更容易开发。目前的办法侧重于端到端的管道,这大大提高了性能,也有助于开发实时用例。

目录

  1. 一种通用的指标检测框架
  2. 什么是 API?为什么咱们须要一个 API?
  3. TensorFlow 对象检测 API

一种通用的指标检测框架

通常,咱们在构建对象检测框架时遵循三个步骤:

  1. 首先,应用深度学习模型或算法在图像中生成一组的边界框(即对象定位)

  1. 接下来,为每个边界框提取视觉特色。它们将依据视觉特色进行评估,并确定框中是否存在以及存在哪些对象

  2. 在最初的后处理步骤中,重叠的框合并为一个边界框(即非最大克制)

就这样,你曾经筹备好了你的第一个指标检测框架!

什么是 API?为什么咱们须要一个 API?

API 代表应用程序编程接口。API 为开发人员提供了一组通用操作,这样他们就不用从头开始编写代码。

想想一个相似于餐馆菜单的 API,它提供了一个菜品列表以及每种菜品的形容。当咱们指定要吃什么菜时,餐厅会为咱们提供成品菜。咱们不晓得餐厅是如何筹备食物的,咱们也不须要。

从某种意义上说,api 是很好的节省时间的工具。在许多状况下,它们也为用户提供了便当。

因而在本文中,咱们将介绍为指标检测工作开发的 TensorFlow API。

TensorFlow 对象检测 API

TensorFlow 对象检测 API 是一个框架,用于创立一个深度学习网络来解决对象检测问题。

在他们的框架中曾经有了预训练的模型,他们称之为 Model Zoo。这包含在 COCO 数据集、KITTI 数据集和 Open Images 数据集上训练的预训练模型的汇合。

它们对于在新数据集上进行训练时也很有用,能够用来初始化。下表形容了预训练模型中应用的各种体系结构:

MobileNet-SSD

SSD 架构是一个单卷积网络,它学习和预测框的地位,并在一次通过中对这些地位进行分类。因而,SSD 能够进行端到端的训练。SSD 网络由根本架构(本例中为 MobileNet)和几个卷积层组成:

SSD 操作特色图以检测边界框的地位。请记住,特色图的大小为 Df Df M。对于每个特色图地位,将预测 k 个边界框。每个边界框都蕴含以下信息:

  • 边界框的 4 个角的 偏移 地位(cx、cy、w、h)
  • 对应类的概率(c1,c2,…cp)

SSD 并不预测盒子的形态,而只是预测盒子的地位。k 个边界框各自具备预约的形态。这些形态是在理论训练之前设置的。例如,在上图中,有 4 个框,示意 k =4。

MobileNet-SSD 损失函数

通过最初一组匹配的框,咱们能够这样计算损失:

L = 1/N (L class + L box)

这里,N 是匹配框的总数。”L class” 是用于分类的 softmax 损失,“L box”是示意匹配框谬误的 L1 平滑损失。L1 平滑损失是 L1 损失的一种修改,它对异样值更具鲁棒性。如果 N 为 0,则损失也设置为 0。

MobileNet

MobileNet 模型是基于一种可分解卷积操作的可拆散深度卷积。它们将一个规范卷积合成为一个深度卷积和一个称为点卷积的 1×1 卷积。

对于 MobileNets,深度卷积对每个输出通道利用单个滤波器。而后,逐点卷积利用 1×1 卷积来合并深度卷积的输入。

一个规范的卷积办法,它既能滤波,又能一步将输出合并成一组新的输入。深度可拆散卷积将其分为两层,一层用于滤波,另一层用于合并。这种合成有显著缩小计算和模型大小的成果。

如何加载模型?

上面是一个循序渐进的过程,遵循 Google Colab。你也能够调试查看代码。

装置模型
!pip install -U --pre tensorflow=="2.*"

确保已装置 pycocotools:

!pip install pycocotools

获取 tensorflow/models 或进入父目录:

import os
import pathlib

if "models" in pathlib.Path.cwd().parts:
  while "models" in pathlib.Path.cwd().parts:
    os.chdir('..')
elif not pathlib.Path('models').exists():
  !git clone --depth 1 https://github.com/tensorflow/models

编译 protobufs 并装置 object_detection 包:

%%bash
cd models/research/
protoc object_detection/protos/*.proto --python_out=.
%%bash 
cd models/research
pip install 
导入所需的库
import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile

from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image
from IPython.display import display

导入对象检测模块:

from object_detection.utils import ops as utils_ops
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util
模型筹备

加载器

def load_model(model_name):
  base_url = 'http://download.tensorflow.org/models/object_detection/'
  model_file = model_name + '.tar.gz'
  model_dir = tf.keras.utils.get_file(
    fname=model_name, 
    origin=base_url + model_file,
    untar=True)

  model_dir = pathlib.Path(model_dir)/"saved_model"

  model = tf.saved_model.load(str(model_dir))
  model = model.signatures['serving_default']

  return model

加载标签 map

标签索引映射到类别名称,以便例如当咱们的卷积网络预测 5 时,咱们就能够晓得这对应于一架飞机:

# 用于为每个框增加正确标签的字符串列表。PATH_TO_LABELS = 'models/research/object_detection/data/mscoco_label_map.pbtxt'
category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)

为了简略起见,咱们将在两个图像上进行测试:

# 如果要用图像测试代码,只需将图像的门路增加到测试图像门路。PATH_TO_TEST_IMAGES_DIR = pathlib.Path('models/research/object_detection/test_images')
TEST_IMAGE_PATHS = sorted(list(PATH_TO_TEST_IMAGES_DIR.glob("*.jpg")))
TEST_IMAGE_PATHS
基于 TensorFlow API 的指标检测模型

加载对象检测模型:

model_name = 'ssd_mobilenet_v1_coco_2017_11_17'
detection_model = load_model(model_name)

查看模型的输出签名(它须要 int8 类型的 3 通道图像):

print(detection_model.inputs)
detection_model.output_dtypes

增加包装函数以调用模型并革除输入:

def run_inference_for_single_image(model, image):
  image = np.asarray(image)
  # 输出必须是张量,请应用“tf.convert to tensor”将其转换。input_tensor = tf.convert_to_tensor(image)
  # 模型须要一批图像,因而增加一个带有“tf.newaxis”的轴。input_tensor = input_tensor[tf.newaxis,...]

  #运行推理
  output_dict = model(input_tensor)

  #所有输入都是张量。# 转换为 numpy 数组,并获取索引 [0] 以删除批处理维度。# 咱们只对第一个 num_detections 检测感兴趣。num_detections = int(output_dict.pop('num_detections'))
  output_dict = {key:value[0, :num_detections].numpy() 
                 for key,value in output_dict.items()}
  output_dict['num_detections'] = num_detections

  # detection_classes 应为 int。.
  output_dict['detection_classes'] = output_dict['detection_classes'].astype(np.int64)
   
  #应用 mask 解决模型:
  if 'detection_masks' in output_dict:
    # 将 bbox mask 从新设置为图像大小.
    detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(output_dict['detection_masks'], output_dict['detection_boxes'],
               image.shape[0], image.shape[1])      
    detection_masks_reframed = tf.cast(detection_masks_reframed > 0.5,
                                       tf.uint8)
    output_dict['detection_masks_reframed'] = detection_masks_reframed.numpy()
    
  return output_dict

在每个测试图像上运行它并显示后果:

def show_inference(model, image_path):
  # 稍后将应用基于数组的图像示意,以便筹备带有框和标签的后果图像。image_np = np.array(Image.open(image_path))
  # 检测.
  output_dict = run_inference_for_single_image(model, image_np)
  # 可视化检测后果
  vis_util.visualize_boxes_and_labels_on_image_array(
      image_np,
      output_dict['detection_boxes'],
      output_dict['detection_classes'],
      output_dict['detection_scores'],
      category_index,
      instance_masks=output_dict.get('detection_masks_reframed', None),
      use_normalized_coordinates=True,
      line_thickness=8)

  display(Image.fromarray(image_np))
for image_path in TEST_IMAGE_PATHS:
  show_inference(detection_model, image_path)

上面是在ssd_mobilenet_v1_coco 上测试的示例图像

Inception-SSD

Inception-SSD 模型的架构与上述 MobileNet SSD 模型的架构类似。区别在于,这里的根本架构是 Inception 模型。

如何加载模型?

只需在 API 的检测局部更改模型名称:

model_name = 'ssd_inception_v1_coco_2017_11_17'
detection_model = load_model(model_name)

而后依照后面的步骤进行预测。

Faster RCNN

目前最先进的指标检测网络依赖于区域倡议算法来假如指标地位。SPPnet 和 Fast-R-CNN 等技术的倒退缩小了这些检测网络的运行工夫。

在 Faster RCNN 中,咱们将输出图像输出到卷积神经网络中生成卷积特色映射。从卷积特色图中,咱们辨认出倡议的区域并将其扭曲成正方形。通过应用一个 RoI(感兴趣区域层)层,咱们将它们重塑成一个固定的大小,这样它就能够被送入一个全连贯层。

从 RoI 特征向量登程,咱们应用 softmax 层来预测提出区域的类别以及边界框的偏移值。

如何加载模型?

只需再次更改 API 的检测局部中的模型名称:

model_name = 'faster_rcnn_resnet101_coco'
detection_model = load_model(model_name)

而后应用与后面雷同的步骤进行预测。上面是给 faster RCNN 模型的示例图像:

如你所见,这比 SSD Mobilenet 模型要好得多。但它比之前的模型慢得多。

你应该抉择哪种指标检测模型?

依据你的特定需要,你能够从 TensorFlow API 中抉择正确的模型。如果咱们想要一个高速模型,SSD 网络的工作成果最好。顾名思义,SSD 网络一次性确定了所有的边界盒概率;因而,它是一个速度更快的模型。

然而,应用 SSD,你能够以就义准确性为代价取得速度。有了 FasterRCNN,咱们将取得高精度,然而速度变慢。

原文链接:https://www.analyticsvidhya.c…

欢送关注磐创 AI 博客站:
http://panchuang.net/

sklearn 机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/

正文完
 0