作者|ALAKH SETHI
編譯|VK
來源|Analytics Vidhya
目標檢測
我喜歡深度學習,坦率地說,這是一個有大量技術和框架可供傾注和學習的廣闊領域,當我看到現實世界中的應用程式,如面部識別和板球跟蹤等時,建立深度學習和計算機視覺模型的真正興奮就來了,
我最喜歡的計算機視覺和深入學習的概念之一是目標檢測,建立一個模型的能力,可以通過影像,告訴我什么樣的物體存在!

當人類看到一幅影像時,我們在幾秒鐘內就能識別出感興趣的物體,機器不是這樣的,因此,目標檢測是一個在影像中定位目標實體的計算機視覺問題,
好訊息是,物件檢測應用程式比以往任何時候都更容易開發,目前的方法側重于端到端的管道,這大大提高了性能,也有助于開發實時用例,
目錄
-
一種通用的目標檢測框架
-
什么是API?為什么我們需要一個API?
-
TensorFlow物件檢測API
一種通用的目標檢測框架
通常,我們在構建物件檢測框架時遵循三個步驟:
- 首先,使用深度學習模型或演算法在影像中生成一組的邊界框(即物件定位)

-
接下來,為每個邊界框提取視覺特征,它們將根據視覺特征進行評估,并確定框中是否存在以及存在哪些物件

-
在最后的后處理步驟中,重疊的框合并為一個邊界框(即非最大抑制)

就這樣,你已經準備好了你的第一個目標檢測框架!
什么是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.com/blog/2020/04/build-your-own-object-detection-model-using-tensorflow-api/
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/2255.html
標籤:其他
下一篇:深度學習分類網路的發展歷史
