SSD300で物体検出
高速で物体検出をしていこうと思うと、SSD(Single Shot MultiBox Detector)と Yolo(You only look once) の二つが人気です。
今回は、そのうちのSSDを使っていきたいと思いますが、先に物体検出ってどういう感じのものかを下に乗せておきます。

それと、この記事ではSSDの中身を詳しく説明するのではなく、まずSSDをどのように実行していけばいいのかを説明していきます。
参考にさせて頂いたサイト
基本的にこのサイトを参考にさせて頂きました。
必要な実行環境
他の記事の「深層学習を用いて画像判定AIを作ってみよう。(その1環境構築)」というもので、Anaconda3でGPU環境を構築する必要があります。
- Tensorflow-gpu 1.12.0
- cuDNN7.1.4
- CUDA9.0
SSD Keras
windowsであれば、コマンドプロンプトから以下を入力して、レポジトリをクローンします。
git clone https://github.com/rykov8/ssd_keras.git
cd ssd_keras
次に、学習済みモデルを https://github.com/rykov8/ssd_keras からダウンロードします。

上のようなページへ移動したら、"here"というリンクに移動し、以下の"weights_SSD300.hdf5"をダウンロードします。
先ほどクローンしたレポジトリのpicsフォルダにサンプル画像が入っているので、ジュピターノートブックから、"SSD.ipynb"を開きます。
ジュピターノートブックを開く際は、コマンドプロンプトに"jupyter notebook "と入力するか、anaconda navigatorから開くこともできます。
そこから、SSD.ipynb を開くと、以下の画像のように先のサンプル画像の物体検出されています。

サンプル画像があるpicsフォルダの画像を自分で検証したいものに取り換えてやってみても良いでしょう。
これで、先のダウンロードした学習済みモデルには、
'Aeroplane', 'Bicycle', 'Bird', 'Boat', 'Bottle',
'Bus', 'Car', 'Cat', 'Chair', 'Cow', 'Diningtable',
'Dog', 'Horse','Motorbike', 'Person', 'Pottedplant',
'Sheep', 'Sofa', 'Train', 'Tvmonitor'
が入っているので、この中のものは検出が可能になります。
もちろん学習済みモデルを独自モデルにすることはできますが、それは後程に。
ですが、今回やりたいことは動画の中での物体検出なので、次に進みます。
そして物体検出に進む前に、Kerasのバージョン2以上の場合は以下の変更が必要になります。変更する箇所が多いので、エディタ機能で置換などを使うと手早くできます。
変更箇所は下にも載せておきましたが、https://qiita.com/ttskng/items/4f67f4bbda2568229956
を参考にさせてもらいました。
ssd.py:
- (13行目) from keras.layers import merge => from keras.layers import concatenate
- (282,290,298,316行目) merge => concatenate
- (258,265,272,287行目) mode='concat'の部分だけ削除
- concat_axis=1 => axis=1
に変更する.
ssd_layers.py :
- (111行目) def get_output_shape_for(self, input_shape): => def compute_output_shape(self, input_shape):
に変更する.
SSD_training.ipynb :
nb_epoch = 30
history = model.fit_generator(gen.generate(True), gen.train_batches,
nb_epoch, verbose=1,
callbacks=callbacks,
validation_data=gen.generate(False),
nb_val_samples=gen.val_batches,
nb_worker=1)
上記の部分を以下に変更する.
epochs = 30
batch_size=16 # 例
history = model.fit_generator(gen.generate(True),
steps_per_epoch =gen.train_batches//batch_size,
epochs=epochs, verbose=1,
callbacks=callbacks,
validation_data=gen.generate(False),
validation_steps=gen.val_batches,
workers=1)
videotest.py:
- (87行目)vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
- (88行目)vidh = vid.get(cv2_CAP_PROP_FRAME_HEIGHT)
- (93行目)vid.set(cv2.CAP_PROP_POS_MSEC, start_frame)
に変更する.
以上のように変更できたら、動画の物体検出に移ります。
まず、ssd_kerasにあるtesting_utils/videotest.pyのコードを修正します。
videotest.py :
- (87行目)vidw = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
- (88行目)vidh = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
に変更する.
また物体検出したい動画を指定するのは、videotest_example.pyで行います。
videotest_example.py :
- (24行目)vid_test.run('path/to/your/video.mkv')のpath/to/your/video.mkvの部分を動画名に変更します。
ここでの検証動画が決まっていない場合には、PEXELS VIDEOS でダウンロードですると良いでしょう。
準備ができたら、"videotest_example.py"と実行してみましょう。

下にサンプル動画を載せておきます。

