使用base标签后图片无法加载_机器如何阅读图片?能看破并说破一切的TensorFlow

全文共3184字,预计学习时长20分钟

8e63b94d52795ec935e7faeda6c401ae.png

图源:engadget

当你看到一张照片时你看到了什么?人们往往几秒钟内就能辨别出自己感兴趣的对象。但机器不是这样,因而它需要目标检测,这是在图片中定位目标实例的计算机视觉问题。

目标检测是深度学习和计算机视觉领域最有趣的概念之一,构建一个能浏览图片并告知图片中有什么对象的模型,多么奇妙的感觉!

好消息是,开发目标检测应用程序比以往更加容易了。如今的方法专注于端到端管道,极大地提高了性能,有助于开发实时用例。

本文将展示如何使用TensorFlow API构建目标检测模型。

fabed090a17e3d67cf039be80a203bf8.png
98c0ffb6cbdba158b298c8387ffb5daf.png

目标检测的总体框架

构建目标检测框架的过程一般分为以下三步:

1、 首先,使用深度学习模型或算法生成一组遍布整张图片的边界框(即目标定位组件)。

8ff19280f9a2f9d3870f23ce113a06f0.png

2、 然后,提取每个边界框的视觉特征,对它们进行评估,并根据视觉特征(即目标分类组件)确定现有边界框中是否存在对象,存在哪些对象。

1bdc517ff3bd17efc72da6359807e5d6.png

3、 在最后的后处理步骤中,将重叠的边界框合并为一个边界框(即非极大值抑制)。

de50f518752a1c4591d68c00fff62190.png

这样就可以开始构建目标检测框架了!

98c0ffb6cbdba158b298c8387ffb5daf.png

什么是API?为什么需要API?

API就像菜单,为客人提供一系列菜品及菜品描述。当顾客点好菜后,饭店开始做菜并上菜。顾客不知道饭店是如何准备饭菜的,也不必知道。

API即应用程序接口。它为开发人员提供一组常用操作以避免从头开始编写代码。

在某种意义上,API是节约时间的好帮手。想一想,用户可以用Facebook账号登录其它应用程序和网站,这非常便捷。是怎么做到的呢?当然是使用脸书的API啦!

a1a77e1fdd9994a798577c721256a113.png

图源:apifriends

98c0ffb6cbdba158b298c8387ffb5daf.png

TensorFlow目标检测API

TensorFlow目标检测API是用于创建解决目标检测问题的深度学习网络框架。

该框架中存在许多预先训练好的模型,因此又被称为模型动物园。它包括一系列基于COCO数据集、KITTI数据集以及Open Images数据集的预训练模型。如果只对数据集中的类别感兴趣,那么可以使用这些模型进行推断。

TensorFlow目标检测API也可以在训练新数据集时对模型初始化。预训练模型中使用的各种架构如下表所示:

53388d479d78e2136be9520087f336b0.png
98c0ffb6cbdba158b298c8387ffb5daf.png

MobileNet-SSD

SSD框架是一个单一卷积网络,可学习预测边界框位置并对其一次性分类。因此,可以端到端地训练SSD。SSD网络由基础架构(本例中为MobileNet-SSD)以及其后的若干卷积层组成:

8c234faee74596ea0b580fe4bfd36b90.png

SSD对特征图进行操作来检测边界框的位置。请记住——特征图大小为Df*Df*M。对于特征图上的每个点,都需预测k个边界框。每个边界框都带有以下信息:

· 4个边界框角坐标偏移值(cx,cy,w,h)

· C个类别概率值(c1,c2...cp)

SSD只预测边界框的位置,而不预测其形状。k个边界框具有各自的预设形状,这些形状是在训练前就设定好的。例如,在上图中有4个框,那么k=4。

MobileNet-SSD的损失

可用最后一组匹配的边界框进行如下的损失计算:

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

其中,N是匹配框的总数;L类是分类的柔性最大值(softmax)损失;‘L box’是L1平滑损失,代表匹配框的误差,L1平滑损失是对L1损失的修正,对异常值具有更强的鲁棒性。在N=0时,损失也设置为0。

MobileNet

MobileNet模型建立在深度可分卷积(一种分解卷积形式)的基础上。这种方法将标准卷积分解为深度卷积和1×1卷积(即逐点卷积)。

对于MobileNets,深度卷积对每个输入通道应用一个滤波器。然后逐点卷积应用1×1卷积来组合深度卷积的输出。

标准的卷积方法中,对输入进行滤波并将其合并为一组新的输出,该过程可在同一步骤中实现。而深度可分卷积将其分为两层,一层用于滤波,一层用于合并。这种分解可以显著减少计算量和模型大小。

817e511f5c7d85819bcef78d30410ac4.png

如何加载模型?

以下是可以遵循的Google Colab上的分步过程,能够轻松可视化目标检测。当然,也可以遵循代码。

安装模型

!pip install -U--pre tensorflow=="2.*"

确保已安装pycocotools:

       !pip installpycocotools

获取 tensorflow/models 或cd 到仓库的父目录:

    import os    import pathlib         if"models"in pathlib.Path.cwd().parts:      while"models"in pathlib.Path.cwd().parts:       os.chdir('..')    elifnot pathlib.Path('models').exists():      !gitclone --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 importStringIO     from matplotlib import pyplot as plt     fromPILimportImage     fromIPython.display import display

导入目标检测模块:

          fromobject_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

模型准备

模型载入器:

         defload_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

载入标签映射

标签映射将索引映射到类别名称,以便当卷积网络预测“5”时,就知道这对应“飞机”。

# List of the stringsthat is used to add correct label for each box.    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)

为了简单说明,对两张图片进行测试:

# If you want to testthe code with your images, just add path to the images to the TEST_IMAGE_PATHS.    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

增加一个包装函数调用模型,并清理输出:

   defrun_inference_for_single_image(model, image):      image = np.asarray(image)       # The input needs tobe a tensor, convert it using `tf.convert_to_tensor`.      input_tensor = tf.convert_to_tensor(image)       # The model expects abatch of images, so add an axis with `tf.newaxis`.      input_tensor = input_tensor[tf.newaxis,...]              # Run inference      output_dict =model(input_tensor)              # All outputs are batches tensors.       # Convert to numpyarrays, and take index [0] to remove the batch dimension.       # We're onlyinterested in the first 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 should be ints.      output_dict['detection_classes'] = output_dict['detection_classes'].astype(np.int64)       # Handle models withmasks:       if'detection_masks'in output_dict:         # Reframe the the bboxmask to the image size.        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

在每张测试图上运行代码,并显示结果:

   defshow_inference(model, image_path):       # the array basedrepresentation of the image will be used later in order to prepare the       # result image withboxes and labels on it.      image_np = np.array(Image.open(image_path))       # Actual detection.      output_dict =run_inference_for_single_image(model, image_np)       # Visualization of theresults of a detection.      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 inTEST_IMAGE_PATHS:      show_inference(detection_model,image_path)

下面是在ssd_mobilenet_v1_coco (在COCO数据集上训练的MobileNet-SSD)上测试的示例图:

d979352653796a2e028558aad52d5d7a.png
98c0ffb6cbdba158b298c8387ffb5daf.png

Inception-SSD

Inception-SSD模型与MobileNet-SSD模型的架构相似。不同之处在于Inception-SSD的基础架构是Inception模型。

如何加载模型?

改变API检测部分的模型名称即可。

     model_name ='ssd_inception_v1_coco_2017_11_17'    detection_model =load_model(model_name)

执行之前所述步骤,做出预测。

98c0ffb6cbdba158b298c8387ffb5daf.png

Faster RCNN

最先进的目标检测网络依赖于候选区域(region proposal)算法来假设目标位置。SPPnet和Fast R-CNN等升级算法已经大大减少了检测网络的运行时间,同时暴露了候选区域计算的瓶颈。

在Faster RCNN中,将图片输入到卷积神经网络以产生卷积特征图。从卷积特征图中,可识别出候选区域并将其捕捉到方框中。通过使用RoI(Region Of Interest layer,感兴趣区域)池化层将其转换为固定的大小,以便将其输入到全连接层。

从RoI特征向量中,使用柔性最大值(softmax)层来预测候选区域的分类和边界框的偏移值。

982c934203300cff7ca8367c1aa3841d.png

如何加载模型?

再次改变API检测部分的模型名称即可。

    model_name ='faster_rcnn_resnet101_coco'    detection_model =load_model(model_name)

然后使用之前所述步骤做出预测。以下是使用Faster RCNN模型的图片示例:

13ca6698a955b33c1d2252e47a905c6a.png

该模型实现的效果比SSD-Mobilenet模型好得多,但它的运行速度要慢得多。当你选择目标检测模型时,必须要做出决定:速度优先还是效果优先。

要结合自己的实际需求从TensorFlowAPI中选择正确的模型。

d469682fc0d7ec5e26ffcebbf93b5871.png

图源:unsplash

如果想要一个能用于检测以高fps速度输入的视频的高速模型,那么最好选用单次目标检测(single-shot detection,SSD)网络。SSD网络可一次性确定所有边界框概率,是一个速度相当快的模型,但它的速度增长需要以损失精确度为代价。而使用Faster RCNN能获得高精确度,但速度较慢。

TensorFlow API还有很多强大之处需要你慢慢去探索!

815b45449a48ae8e2988222bf900289c.png

留言点赞关注

我们一起分享AI学习与发展的干货

如转载,请后台留言,遵守转载规范

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值