トップページ人工知能,実世界DB物体認識SSD による一般物体検出(SnowMasaya/ssd_keras, Python 3.6,TensorFlow 1.15, Keras 2.0.9 を使用)

SSD による一般物体検出(SnowMasaya/ssd_keras, Python 3.6,TensorFlow 1.15, Keras 2.0.9 を使用)

画像の物体認識を行ってみる. 学習については,学習結果のファイルを所定のサイトからダウンロードしてみる.

目次

  1. 前準備
  2. TensorFlow 1.15(旧バージョン),Keras 2.0.9(旧バージョン)のインストール
  3. SnowMasaya/ssd_keras のインストール
  4. SSD を行ってみる

入力画像の例

[image]

出力としては「種類」を表すラベル(下の図では「Person」や「Bicycle」)と、バウンディングボックス

[image]

URL: https://github.com/SnowMasaya/ssd_keras

手順の要点: Python 3.6, TensorFlow 1.15, Python の隔離された環境(Windows では C:\venv\tf115py36)

ソフトウエア等の利用条件等は,利用者で確認すること.

謝辞:ソフトウエアの作者に感謝します.

前準備

TensorFlow 1.15 を使う.

(Windows を使う場合のみ)マイクロソフト C++ ビルドツール (Build Tools) のインストール

Visual Studio Community 2019 vesion 16.2, マイクロソフト C++ ビルドツールのインストール(Windows 上)」で説明している.

Python,TensorFlow 1.15 のインストール

すでに TensorFlow 2 を使っている,あるいは使う予定ということがありえる. 単純には,TensorFlow 2 と TensorFlow 1.15 を共存させて Python で使うということはできないが, 少しの手間で,共存できるようになる. そこで,TensorFlow 2 とTensorFlow 1.15 の共存を前提として, TensorFlow 1.15 のインストールを行う.

Python 開発環境のインストール】

Python を使うときは,Python開発環境や Python コンソール(Jupyter Qt ConsoleSpyderPyCharmPyScripter など)の利用も便利である

Windows, Ubuntu での Python 開発環境,Python コンソールJupyter Qt Console, Jupyter ノートブック (Jupyter Notebook), Jupyter Lab, Nteract, spyder)のインストール: 別ページで,インストール手順を説明している.

Windows の場合

Windows でのPython3.6TensorFlow 1.15 のインストール:別ページで説明している.

すでにPython 3.9 あるいは Python 3.8 をインストールしている,あるいは,インストール予定という場合を想定し, あとのトラブルが起きにくい,そして,簡単に運用できるように 「Python 3.6 をインストールし,その上に,TensorFlow 1.15.5 をインストールする」という手順を案内している.

Ubuntu の場合

Ubuntu でのPythonTensorFlow 1.15 のインストール:別ページで案内している.

Ubuntu のシステム Python に影響を与えないように,隔離された Python 3.6 仮想環境の新規作成し,その上にTensorFlow 1.15.5 をインストールするという手順(venv を使用)(Ubuntu 上)を案内している.

Git のインストール

Git の URL: https://git-scm.com/

SnowMasaya/ssd_keras のインストール

Windows での手順を下に示す.Ubuntu でも同様の手順になる.

  1. Windows で,コマンドプロンプト管理者として実行する.

    [image]
  2. numpy, imageio のインストール

    python -m pip install -U numpy imageio
    python -m pip install -U jupyterlab jupyter jupyter-console jupytext spyder
    
  3. ディレクトリ(フォルダ)を空にする操作

    cd c:\pytools
    rmdir /s /q ssd_keras
    

    [image]
  4. SnowMasaya/ssd_keras のインストール

    git clone https://github.com/SnowMasaya/ssd_keras
    

    [image]
  5. rykov ssd_keras の Web ページに記載の通り,次のWebページを開く

    https://mega.nz/#F!7RowVLCL!q3cEVRK9jyOSB9el3SssIA

  6. 2つの hdfファイルが表示されるので確認する.

    [image]
  7. 2つともダウンロードしたい. 「ZIPとしてダウンロードする」をクリック.

    [image]
  8. SSD.zip というファイルのダウンロードが始まるので確認する.

    [image]
  9. SSD.zip を展開(解凍)し,できたファイルを c:\pytools\ssd_kerasに置く.

    下の図のように

    [image]

SSD を行ってみる

Python コンソールで,SSD.ipynb に記載のコマンドを実行しながら結果を確認したい.結果は,画像などでプロットされる場合がある.

Windows での手順を下に示す.Ubuntu でも同様の手順になる.

  1. Windows で,コマンドプロンプト管理者として実行する.

    [image]
  2. カレントディレクトリ

    cd c:\pytools\ssd_keras
    

    [image]
  3. 使用する GPU のメモリ量を制限したい場合のみ

    次を実行.「1024」のところは,適切に調整すること.

    https://www.tensorflow.org/guide/gpu に記載の手順による.

    from __future__ import absolute_import, division, print_function, unicode_literals
    import tensorflow as tf
    
    gpus = tf.config.experimental.list_physical_devices('GPU')
    if gpus:
      # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
      try:
        tf.config.experimental.set_virtual_device_configuration(
            gpus[0],
            [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
        logical_gpus = tf.config.experimental.list_logical_devices('GPU')
        print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
      except RuntimeError as e:
        # Virtual devices must be set before GPUs have been initialized
        print(e)
    

    [image]
  4. ステップ 1 (初期設定)

    次の Python プログラムを実行

    https://github.com/SnowMasaya/ssd_keras/blob/master/SSD.ipynb の「in [1]」に記載の通り.

    from __future__ import absolute_import, division, print_function, unicode_literals
    
    from keras.applications.imagenet_utils import preprocess_input
    from keras.backend.tensorflow_backend import set_session
    from tensorflow.keras.preprocessing import image
    %matplotlib inline
    import matplotlib.pyplot as plt
    import warnings
    warnings.filterwarnings('ignore')   # Suppress Matplotlib warnings
    import numpy as np
    from imageio import imread
    import tensorflow as tf
    
    from ssd_v2 import SSD300v2
    from ssd_utils import BBoxUtility
    import os
    
    plt.rcParams['figure.figsize'] = (8, 8)
    plt.rcParams['image.interpolation'] = 'nearest'
    
    np.set_printoptions(suppress=True)
    

    [image]

    次のようなエラーが出たときは, 「sys.path.append("c:\pytools\ssd_keras")」のようなコマンドを実行の後,やり直す.

  5. ステップ 2 (種類の設定)

    次の Python プログラムを実行

    https://github.com/SnowMasaya/ssd_keras/blob/master/SSD.ipynb の「in [2]」に記載の通り.

    voc_classes = ['Aeroplane', 'Bicycle', 'Bird', 'Boat', 'Bottle',
                   'Bus', 'Car', 'Cat', 'Chair', 'Cow', 'Diningtable',
                   'Dog', 'Horse','Motorbike', 'Person', 'Pottedplant',
                   'Sheep', 'Sofa', 'Train', 'Tvmonitor']
    NUM_CLASSES = len(voc_classes) + 1
    

    [image]
  6. ステップ 3 (先ほどダウンロードした学習結果ファイル weights_SSD300.hdf5 の読み込み

    次の Python プログラムを実行

    https://github.com/SnowMasaya/ssd_keras/blob/master/SSD.ipynb の「in [3]」に記載の通り.

    input_shape=(300, 300, 3)
    model = SSD300v2(input_shape, num_classes=NUM_CLASSES)
    model.load_weights('weights_SSD300.hdf5', by_name=True)
    bbox_util = BBoxUtility(NUM_CLASSES)
    

    [image]
  7. ステップ 4 (処理したい入力画像ファイル 5つの読み込み設定)

    次の Python プログラムを実行

    https://github.com/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [4]」に記載の通り.

    inputs = []
    images = []
    img_path = './pics/fish-bike.jpg'
    img = image.load_img(img_path, target_size=(300, 300))
    img = image.img_to_array(img)
    images.append(imread(img_path))
    inputs.append(img.copy())
    img_path = './pics/cat.jpg'
    img = image.load_img(img_path, target_size=(300, 300))
    img = image.img_to_array(img)
    images.append(imread(img_path))
    inputs.append(img.copy())
    img_path = './pics/boys.jpg'
    img = image.load_img(img_path, target_size=(300, 300))
    img = image.img_to_array(img)
    images.append(imread(img_path))
    inputs.append(img.copy())
    img_path = './pics/car_cat.jpg'
    img = image.load_img(img_path, target_size=(300, 300))
    img = image.img_to_array(img)
    images.append(imread(img_path))
    inputs.append(img.copy())
    img_path = './pics/car_cat2.jpg'
    img = image.load_img(img_path, target_size=(300, 300))
    img = image.img_to_array(img)
    images.append(imread(img_path))
    inputs.append(img.copy())
    inputs = preprocess_input(np.array(inputs))
    

    [image]
  8. ステップ 5 (予測処理)

    次の Python プログラムを実行

    https://github.com/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [5]」に記載の通り.

    preds = model.predict(inputs, batch_size=1, verbose=1)
    

    [image]
  9. ステップ 6 (予測結果からバウンディングボックスを作るという後処理)

    次の Python プログラムを実行

    https://github.com/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [6]」に記載の通り.

    results = bbox_util.detection_out(preds)
    

    [image]
  10. 最後のステップ (結果の表示)

    次の Python プログラムを実行

    https://github.com/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [8]」に記載の通り.

    for i, img in enumerate(images):
        # Parse the outputs.
        det_label = results[i][:, 0]
        det_conf = results[i][:, 1]
        det_xmin = results[i][:, 2]
        det_ymin = results[i][:, 3]
        det_xmax = results[i][:, 4]
        det_ymax = results[i][:, 5]
    
        # Get detections with confidence higher than 0.6.
        top_indices = [i for i, conf in enumerate(det_conf) if conf >= 0.6]
    
        top_conf = det_conf[top_indices]
        top_label_indices = det_label[top_indices].tolist()
        top_xmin = det_xmin[top_indices]
        top_ymin = det_ymin[top_indices]
        top_xmax = det_xmax[top_indices]
        top_ymax = det_ymax[top_indices]
    
        colors = plt.cm.hsv(np.linspace(0, 1, 21)).tolist()
    
        plt.figure()
        plt.imshow(img / 255.)
        currentAxis = plt.gca()
    
        for i in range(top_conf.shape[0]):
            xmin = int(round(top_xmin[i] * img.shape[1]))
            ymin = int(round(top_ymin[i] * img.shape[0]))
            xmax = int(round(top_xmax[i] * img.shape[1]))
            ymax = int(round(top_ymax[i] * img.shape[0]))
            score = top_conf[i]
            label = int(top_label_indices[i])
            label_name = voc_classes[label - 1]
            display_txt = '{:0.2f}, {}'.format(score, label_name)
            coords = (xmin, ymin), xmax-xmin+1, ymax-ymin+1
            color = colors[label]
            currentAxis.add_patch(plt.Rectangle(*coords, fill=False, edgecolor=color, linewidth=2))
            currentAxis.text(xmin, ymin, display_txt, bbox={'facecolor':color, 'alpha':0.5})
        
        plt.show()
    

    [image]

    実行結果

    [image]