SSD Keras の実装である rykov ssd_keras を使ってみる.
目次
URL: https://github.com/rykov8/ssd_keras
手順の要点: Python 3.6, TensorFlow 1.15, Python の隔離された環境(Windows では C:\venv\tf115py36)
ソフトウエア等の利用条件等は,利用者で確認すること.
謝辞:ソフトウエアの作者に感謝します.
TensorFlow 1.15 を使う.
「Visual Studio Community 2019 vesion 16.2, マイクロソフト C++ ビルドツールのインストール(Windows 上)」で説明している.
すでに TensorFlow 2 を使っている,あるいは使う予定ということがありえる. 単純には,TensorFlow 2 と TensorFlow 1.15 を共存させて Python で使うということはできないが, 少しの手間で,共存できるようになる. そこで,TensorFlow 2 とTensorFlow 1.15 の共存を前提として, TensorFlow 1.15 のインストールを行う.
【Python 開発環境のインストール】
Python を使うときは,Python開発環境や Python コンソール(Jupyter Qt Console,Spyder,PyCharm,PyScripter など)の利用も便利である
Windows, Ubuntu での Python 開発環境,Python コンソール(Jupyter Qt Console, Jupyter ノートブック (Jupyter Notebook), Jupyter Lab, Nteract, spyder)のインストール: 別ページで,インストール手順を説明している.
Windows でのPython3.6,TensorFlow 1.15 のインストール:別ページで説明している.
すでにPython 3.9 あるいは Python 3.8 をインストールしている,あるいは,インストール予定という場合を想定し, あとのトラブルが起きにくい,そして,簡単に運用できるように 「Python 3.6 をインストールし,その上に,TensorFlow 1.15.5 をインストールする」という手順を案内している.
Ubuntu でのPython,TensorFlow 1.15 のインストール:別ページで案内している.
Ubuntu のシステム Python に影響を与えないように,隔離された Python 3.6 仮想環境の新規作成し,その上にTensorFlow 1.15.5 をインストールするという手順(venv を使用)(Ubuntu 上)を案内している.
osudo apt -y install git
Windows での手順を下に示す.Ubuntu でも同様の手順になる.
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
cd c:\pytools rmdir /s /q ssd_keras
git clone https://github.com/rykov8/ssd_keras
下の図のように
Python コンソールで,SSD.ipynb に記載のコマンドを実行しながら結果を確認したい.結果は,画像などでプロットされる場合がある.
Windows での手順を下に示す.Ubuntu でも同様の手順になる.
cd c:\pytools\ssd_keras
次を実行.「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)
次の 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)
次の 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
次の 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)
次の 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))
次の Python プログラムを実行
※ https://github.com/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [5]」に記載の通り.
preds = model.predict(inputs, batch_size=1, verbose=1)
次の Python プログラムを実行
※ https://github.com/rykov8/ssd_keras/blob/master/SSD.ipynb の「in [6]」に記載の通り.
results = bbox_util.detection_out(preds)
次の 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()
実行結果