[ TensorFlow ] VGG16さんをメガネの形状判定が出来る優れたモデルに作り変える ( 転移学習 )

[ TensorFlow ] VGG16さんをメガネの形状判定が出来る優れたモデルに作り変える ( 転移学習 )

 

本記事では、TensorFlow で用意されたモデルを使用し、転移学習を行う方法について解説します。
今回は、VGG16モデルをベースに、メガネの形状を識別出来る様な新しいモデルを構築していきます。

 

学習済みモデルとは(復習)

以前、我が家の犬の犬種を識別するプログラムを実装しました。

あの時使用したのは TensorFlow にあらかじめ用意されている VGG16 というモデルでした。
このモデルにはすでに犬のデータを用いた学習が行われており、犬のデータを識別可能な状態にあります。

この様に、対象データについての学習を既に終えているモデルのことを ” 学習済みモデル(Pre-Trained Model) ” と呼びます。

画像の識別を行いたいと思った時、既に学習済みのモデルが存在するのであればモデル構築のプロセスを殆どスキップ出来るため、モデル構築に当たっては先ず検討したい方法です。

学習していない画像に対する反応

ちなみに、未学習の画像に対するモデルの反応を見ておきたいと思います。

犬種判定にめっぽう強いVGG16さんに、メガネの画像を渡してみます。

 

送風機、あるいは笛…?
まるっきり、判定できていませんね。彼にとってこれはまるっきり未知の画像ですから、しょうがないです。

 

転移学習とは

識別を行いたい画像に対して学習を行なっている様なモデルが世に存在しないときは、自分でモデルを構築しなければなりません。
しかしそんな時でも、既に存在するモデルを流用することが出来ます。

その方法が、” 転移学習 ( transfer learning ) ” です。これは既に存在するモデルのネットワークはそのままに、全結合層のみを新規に作成し再学習させるという方法です。

例えば先に例を出した VGG16モデル は、対象画像の特徴量を適切に抽出出来る様なネットワークを保持しています。ただ、取得した特徴量と新規画像との紐付けが出来ないだけです。

なので、VGG16モデルをベースにしつつ、特徴量とカテゴライズの機能だけを刷新してやれば新規の画像に対しても識別可能なモデルが完成する、という考え方です。

 

今回はこの考え方に則って、メガネの画像に対する画像識別を行なっていきたいと思います。

 

目的

タイトルにある通り、今回の目的はメガネの形状を識別することです。

具体的な仕様は次の通りです。

 

[ モデル ]
VGG16モデルをベースに転移学習を行なったもの

[ 機能 ]
与えられたメガネの画像に対して形状識別を行い、以下のいずれかの形状であるかを判定する。
・丸メガネ(round_glasses)
・スクエアメガネ(square_glasses)
・ウェリントン型メガネ(wellington_glasses)

[ 画像 ]
以下の画像を用意する。
・丸メガネ…110枚
・スクエアメガネ…110枚
・ウェリントン型メガネ…110枚

なお、上記画像を以下の様に分割する。
・訓練用データ…各6割
・検証用データ…各3割
・テスト用データ…各1割

 

実装

ラベリング

実装に入る前に、画像データのラベリングについてです。

今回は keras の ImageDataGenerator クラスのメソッド flow_from_directory を使用しますが、こいつは指定ディレクトリ内の画像をディレクトリ名でラベル付けしてくれるという優れものです。

ですので、各ディレクトリには round_grasses などのラベル名を付けた上で画像を格納しています。

| — train —       | — round_glasses
|                            | — square_glasses
|                            | — wellington_glasses
| — validate —  | — round_glasses
.                            | — square_glasses
.                            | — wellington_glasses

 

ちなみに各ディレクトリの下には、このような画像がたくさん入っています。
画像を集めるのが一番大変でした。

  1. round_glasses
  2. square_glasses
  3. wellington_glasses

 

スクエアなメガネとウェリントンのメガネの識別が、難しそうですね。

 

実装

では早速実装に入っていきます。今回はちょっと長いので、分割しながらみていきます。

  1. モデル構築用の関数を定義します。15層目までの重みを固定(再学習させない)した上で、全結合層を追加します。今回は3クラス分類なので、最終出力は3次元です。
  2. VGG16モデルを呼び出します。全結合層はimportしません。

     
  3. VGG16をベースに、モデルを再構築します。modelが4なのは、3回失敗したからです…。

     
  4. ジェネレータを定義します。今回は訓練用画像用のジェネレータに、データ拡張の設定を施します。
  5. ジェネレータを使用して、画像に対するイテレータを作成します。用意しておいた画像を格納しているディレクトリを指定します。この際、イテレータ先の画像を読み込む際のバッチサイズなどを指定します。
  6. モデル、ネットワーク、ログの保存設定をします。
  7. 学習を実行します。

出力ログ

回数が増えるにつれ、損失が減少し正解率が上昇しているのがわかります。

 

識別の実行

ここまでで学習は終了したので、実際の画像を渡して画像の識別を行なってみましょう。

テスト用ディレクトリからランダムに画像を15枚抜き出し、それぞれをモデルに判定させ、各画像のタイトルに識別結果を付与するようにしています。

識別率は8割といったところなのでところどころ間違いはありますが、概ね正しく識別できていることが確認できます。

 

やはり、スクエアなメガネとウェリントンメガネの識別が難しい様ですね…。

 

まとめ

  • 未知の画像に対して画像識別可能なモデルを構築したい時には、既存のモデルを流用する 転移学習 という手法を取ることが出来る。
  • データ拡張で画像の水増しは可能だが、ある程度の数は必要。(各画像20枚で学習させても上手く行かず、100枚で良い感じに)
  • データ拡張はし過ぎてもいけないし、しなさ過ぎてもいけない。(記事外で、試行錯誤の過程がありました)
  • 画像を集めて振り分けるのが一番面倒。

 

以上

TensorFlowカテゴリの最新記事