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

SSD による一般物体検出(rykov SSD_Keras, Python 3.6, TensorFlow 1.15, Keras 1.2.2 を使用)

SSD Keras の実装である rykov ssd_keras を使ってみる.

目次

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

URL: https://github.com/rykov8/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 のインストール

rykov ssd_keras のインストール

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

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

    [image]
  2. keras matplotlib numpy imageio などのインストール

    venv を使い,孤立した Python の隔離された環境を使っているときは,Windows でも Ubuntu でも同じで,「python -m pip install ...」.

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

    cd c:\pytools
    rmdir /s /q ssd_keras
    

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

    git clone https://github.com/rykov8/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 を展開(解凍)し,できたファイルを先ほど展開したディレクトリに置く.

    下の図のように

    [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/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [1]」に記載の通り.

    from __future__ import absolute_import, division, print_function, unicode_literals
    
    import cv2
    import keras
    from keras.applications.imagenet_utils import preprocess_input
    from keras.backend.tensorflow_backend import set_session
    from keras.models import Model
    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 import SSD300
    from ssd_utils import BBoxUtility
    
    plt.rcParams['figure.figsize'] = (8, 8)
    plt.rcParams['image.interpolation'] = 'nearest'
    
    np.set_printoptions(suppress=True)
    

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

    次の Python プログラムを実行

    https://github.com/rykov8/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/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [3]」に記載の通り.

    input_shape=(300, 300, 3)
    model = SSD300(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]