TenosorFlow 一般物体検出 API
作成 : (株)クラスキャット セールスインフォメーション
日時 : 06/20/2017
Google Research Blog の 6月15日付けの記事によれば、TensorFlow ベースの「一般物体検出 API (Object Detection API)」を公開して利用可能にしたとのことです :
物体検出の先端技術である Faster R-CNN や SSD が利用可能になっています。
日本語記事では以下の techcrunch ベースの記事が詳しいです :
- GoogleがTensorFlowによるオブジェクト検出APIをリリース、機械学習のデベロッパー利用がますます簡単に
- Google releases new TensorFlow Object Detection API (原文)
一般物体検出については TensorFlow で「一般物体検出」入門 も参考にしてください。
以下は実際にチュートリアルで検出を実行して出力した画像サンプルです :
チュートリアル
jupyter ベースのチュートリアルが用意されていますので、さっそく試してみましょう。
Imports
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
環境設定
%matplotlib inline sys.path.append("..")
物体検出 imports
from utils import label_map_util from utils import visualization_utils as vis_util
モデル準備
変数
export_inference_graph.py ツールを使用して export されたモデルはどれでも単に PATH_TO_CKPT を新しい .pb ファイルを指すように変更することでここでロード可能です。
ここでデフォルトでは “SSD with Mobilenet” を使用します。他のモデルのリストについては detection model zoo を見てください、様々な速度と精度の創造的なモデルを実行することができます。
# What model to download. MODEL_NAME = 'ssd_mobilenet_v1_coco_11_06_2017' MODEL_FILE = MODEL_NAME + '.tar.gz' DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/' # Path to frozen detection graph. This is the actual model that is used for the object detection. PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb' # List of the strings that is used to add correct label for each box. PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt') NUM_CLASSES = 90
モデルのダウンロード
opener = urllib.request.URLopener() opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE) tar_file = tarfile.open(MODEL_FILE) for file in tar_file.getmembers(): file_name = os.path.basename(file.name) if 'frozen_inference_graph.pb' in file_name: tar_file.extract(file, os.getcwd())
(凍結した (frozen)) Tensorflor モデルをメモリにロードする
detection_graph = tf.Graph() with detection_graph.as_default(): od_graph_def = tf.GraphDef() with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid: serialized_graph = fid.read() od_graph_def.ParseFromString(serialized_graph) tf.import_graph_def(od_graph_def, name='')
ラベル・マップをロードする
ラベル・マップはインデックスをカテゴリー名にマップします、その結果、畳み込みネットワークが 5 と予測したときにこれが飛行機に相当することを知ることができます。ここでは内部的なユティリティ関数を使用しますが、整数を適切な文字列ラベルにマップする辞書を返すのであればどんなものでもかまいません。
label_map = label_map_util.load_labelmap(PATH_TO_LABELS) categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True) category_index = label_map_util.create_category_index(categories)
ヘルパー・コード
def load_image_into_numpy_array(image): (im_width, im_height) = image.size return np.array(image.getdata()).reshape( (im_height, im_width, 3)).astype(np.uint8)
検出
# For the sake of simplicity we will use only 2 images: # image1.jpg # image2.jpg # If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS. PATH_TO_TEST_IMAGES_DIR = 'test_images' TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ] # Size, in inches, of the output images. IMAGE_SIZE = (12, 8)
with detection_graph.as_default(): with tf.Session(graph=detection_graph) as sess: for image_path in TEST_IMAGE_PATHS: image = Image.open(image_path) # the array based representation of the image will be used later in order to prepare the # result image with boxes and labels on it. image_np = load_image_into_numpy_array(image) # Expand dimensions since the model expects images to have shape: [1, None, None, 3] image_np_expanded = np.expand_dims(image_np, axis=0) image_tensor = detection_graph.get_tensor_by_name('image_tensor:0') # Each box represents a part of the image where a particular object was detected. boxes = detection_graph.get_tensor_by_name('detection_boxes:0') # Each score represent how level of confidence for each of the objects. # Score is shown on the result image, together with the class label. scores = detection_graph.get_tensor_by_name('detection_scores:0') classes = detection_graph.get_tensor_by_name('detection_classes:0') num_detections = detection_graph.get_tensor_by_name('num_detections:0') # Actual detection. (boxes, scores, classes, num_detections) = sess.run( [boxes, scores, classes, num_detections], feed_dict={image_tensor: image_np_expanded}) # Visualization of the results of a detection. vis_util.visualize_boxes_and_labels_on_image_array( image_np, np.squeeze(boxes), np.squeeze(classes).astype(np.int32), np.squeeze(scores), category_index, use_normalized_coordinates=True, line_thickness=8) plt.figure(figsize=IMAGE_SIZE) plt.imshow(image_np)
デフォルトでは以下の2つが表示されます :
テスト画像を入れ替えてみます。最初はクラスキャットのマスコット猫 :
以下は ImageNet からの画像です (* 元画像の版権は所有者に帰属します) :
以上