Pythonを学んで1年ちょっとの初心者が、物体検出プログラム(SSD)を作成し、実務を想定して改良してみた話

2020年9月1日

物体検知プログラム(SSD)でC1608コンデンサを検知させた様子
物体検知プログラム(SSD)でC1608コンデンサを検知させた様子

今回は物体検出技術について紹介します。

Pythonの高度なプログラミングスキルは不要です。

簡単な画像分類プログラムのソースコードが読めるレベルなら問題なく理解できると思います。

物体検知で何ができるの?

画面(または画像)に映った物体の位置推定とクラス分類(種類分け)が同時にできる技術です。

この技術を使うと画面のどこに何が映っているのかが瞬時に分かります。

また画面に複数の物体が映っていても、位置と種類が判別できます。

物体分類との学習方法の違いについて

物体検出では、物体の「クラス(種類)」と同時に「位置情報」を学習させる必要があります。

学習には物体検出用のSSDネットワークを使います。

これは、ベースネットワーク(ここではVGG16)と追加ネットワーク(Extra Feature Layers)を結合したネットワークです。

このSSDネットワークを使って学習を行い推論モデルを作成します。

次に、作成した推論モデルを使って画面(または画像)に映った物体の位置とクラス(種類)を検出します。

物体検出させた様子の一例が表題下の画像になります。

物体をバインディングボックスと呼ばれる枠で囲い、左上にクラス(種類)と推論確率(1.00は100%)を示しています。

参考にした書籍

プログラム作成時に参考にした書籍(一部)を紹介します。

書籍の画像は左側から1番~4番を示しています。

  1. Pythonで動かして学ぶ! あたらしい深層学習の教科書((株)翔泳社)
  2. PythonとKerasによるディープラーニング((株)マイナビ出版)
  3. PyTorchニューラルネットワーク実装ハンドブック((株)秀和システム)
  4. つくりながら学ぶ! PyTorchによる発展ディープラーニング((株)マイナビ出版)

1番と2番は非常に丁寧に説明されており、ソースコードもシンプルで分かりやすく書かれています。

繰り返し読むことで理解が深まり新しい発見があります。

手元に置いて損しない本です。

2番目の本は、keras の生みの親 Francois Chollet(フランソワ・ショレ)氏が書いた本です。

この本は Python と keras を使ったソースコードが豊富です。

プログラミングの習得には、ソースコードを自分で入力して実行させてみることが大事です。

同じように入力したはずなのに、動作しないこともあると思います。

ほとんどは入力ミスが原因で、インデント(字下げ)の位置が間違っていたり、単語の間違いがほとんどです。

大切なのはそのミスに自分で気づくことなんです。

プログラムを学ぶということは気づきの訓練にもなります。

気づきの感度を上げることは、プログラミングだけでなく普段の生活や仕事の面でも役に立ちます。

1番と2番の本をある程度理解したら、次に3番と4番の本を読んで欲しいです。

物体検出のプログラムが書いてあるのは3番と4番なんですが内容が難しいです。

まずは1番と2番の書籍から学習を始めることをおすすめします。

なお、1番と2番の本を勉強すれば画像分類のプログラムなら作成できるようになると思います。

画像分類とは画像に映った物体が何かを判定するプログラムです。

なお、画像分類として紹介されている一般的なプログラムには欠点があります。

それは、画像に複数の物体が映っていると、分類して欲しい物体をうまく見分けて分類することができないというものです。

基本的には、1画像には1種類の物体しか映っていないことが前提となります。

プログラムを若干工夫すれば複数物体でも分類できると思いますが、それなら物体検出プログラムを作ればよいことになるので、単純に物体分類プログラムの進化版が物体検出プログラムだと考えればよいと思います。

物体検出プログラムの種類

代表的な物体検出プログラムは、YOLO(You only look once)とSSD(Single Shot MultiBox Detector)です。

何れもリアルタイムでの物体検出が得意なプログラムです。

ここでは、SSDの物体検出プログラムを紹介します。

物体検出の様子(動画)

以下の動画をご覧ください。

SSDで物体検出

動画内で実行している内容を順に説明します。

動画内でやっていること

この動画では以下のことを実行しています。

  • 1608サイズのコンデンサ(大きさが、約1.6mm×0.8mm)を認識
  • コンデンサを認識したときマル印(〇)が表示
  • 画面に映ったコンデンサの数量を数える
  • コンデンサを5円/個と仮定したときの合計金額(=数量×個数)を計算
  • 物体名、数量、合計金額を画面にリアルタイム表示

コンデンサは、ガラスシャーレの中に適当に入れてあります。

何も映っていない場合は右上の画面の判定は表示されません。

コンデンサを認識したときマル印(〇)が表示されるようになっています。

なお、余談ですがサイズが異なるものや変色、変形等があった場合はバツ印(×)を表示させたり、バインディングボックスの色を変えたり、異常を声でお知らせすることも可能です。

実際の現場で物体検出を適用する場合リアルタイム処理が必要になると思います。

SSDによる物体検出プログラムは物体分類プログラムに比べ計算負荷が大きく複雑です。

物体検出させるだけでなく、そこから得られた情報(位置データや出現回数、クラス分類情報等)をプログラム内部で次のタスクに利用することも想定されます。

このため、計算負荷に耐える高性能なパソコンと実行速度を上げるためのソースコードの最適化が必要になります。

リアルタイム処理に必要なマシンスペック

動画撮影時のマシンスペック(主なパーツ)は以下です。

カテゴリー製品名
CPUIntel Core i9-9900K
マザーボードASUSTek ROG STRIX Z390-F GAMING
メモリCORSAIR DDR4-2666MHz
VENGEANCE LPX Series 16GB×2枚キット CMK32GX4M2A2666C16
ビデオカードASUS NVIDIA RTX2080Ti 搭載 トリプルファンモデル 11GB
SSDSamsung SSD 1TB 970 EVO Plus M.2 Type2280 PCIe3.0×4 NVMe1.3
電源Cooler Master V1200 Platinum 1200W
CPUクーラーCooler Master MasterLiquid ML240L RGB 水冷

なぜこのスペックが必要なのか。

それは、推論モデル作成時の計算負荷がバカにならないからです。

計算負荷が大きいということは、CPUの発熱はもとより、計算時間にもの凄く影響を及ぼします。

一般的に、推論精度の高いモデルを作成する場合、転移学習などによりモデルを何度も作り直します。

学習させる画像の最適化(枚数や物体の大きさ等)はもとより、計算パラメータを微調整したり、学習率を変えて何千回も繰り返し計算させます。

学習時の計算時間はマシンスペックにも依りますが、数十分~数時間、場合によっては数日かかることもあります。

実務での使用を想定すると現実的ではありません。

このため、推論精度の高いモデルを短時間で作成する場合、ある程度のマシンスペックが必要になります。

なお、一番計算負荷が大きいのは学習時です。

すでに推論モデルが出来上がっており推論するだけであれば、ここまでのマシンスペックは必要ないと思います。

使えるシチュエーションは?

  • 商品の種類ごとに数を瞬時に数えたい。
  • 商品の異常を瞬時に見つけたい。
  • 商品の値段が分かっていれば、瞬時に合計金額を知りたい。

などが考えられます。

もちろん、これらの数値データを画面に表示させるだけではなく、次のタスクに利用することもできます。

いろんな可能性を感じる技術だと思います。

まとめ

  • SSDによる物体検出プログラムでリアルタイムに物体の位置と種類を判別することができる。
  • 学習にはSSDネットワークを用いる。
  • 学習時は、物体の位置情報とクラス(種類)を同時に学習させる必要がある。
  • 学習にはかなりのマシンスペックが必要である。

あとがき

はじめて画像分類のプログラムが作成できたときは、声を上げて喜びました。

まともに動くようになるまで数ヶ月は悩んでいました。

プログラムの知識や経験も浅かったため、画像データがプログラム内部でどのように扱われているのか分かっていなかったことが原因でした。

それに気づくのにそれだけの時間が掛かりました。

そこからはプログラムの理解が速かったと記憶しています。

物体分類から物体検出、セマンティックセグメンテーションまで一気に学習しました。

一周回ってもう一度基礎から学習しています。

また新たな発見があり、また理解も深まりました。

物体検知はワクワクします。

明らかに自分の能力を超えた認識能力を示してくれます。

素直にすごいと思うしもっと成長させたいと思うんです。

最近は色んなアイディアをソースコードに落とし込めるようになってきました。

新しいプログラムができたらまた紹介します。

今日はこの辺にしたいと思います。

ここまで読んでいただき、ありがとうございました。