何の話かというと
TensorFlow TutorialsのConvolutional Neural Networksでは、CIFAR-10と呼ばれる画像データセットの分類問題にCNNを適用しています。
CIFAR-10は、次のような "airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck" の10種類の画像データセットで、これらを自動的に分類するモデルを構築するというものです。
使用するモデルそのものは、本質的には、下記の記事で紹介したCNNと同じです。畳み込みが2層で、最後の特徴変数と取り出す全結合層も2段になっています。
ただし、上記の記事の問題(手書き文字の分類)との大きな違いは、与えられた画像の複雑さです。手書き文字のデータは、グレースケールで識別対象の数字のみが鮮明に表示されています。基本的には、文字の形から特徴を抽出すればよさそうなことがわかります。
一方、CIFAR-10のデータは、実写画像なので、次のような点を考慮して特徴を抽出する必要が出てきます。
・識別対象以外の物体が周囲に写っている。
・識別対象が画像の中心にあるとは限らない。
・画像の明るさやコントラストが一定ではない。
これらの問題に対応するために、与えられた画像をそのまま利用するのではなく、いくつかの「前処理」を施すということを行っています。本記事では、これらの前処理について解説します。
判定処理の入力画像
まず、モデルのトレーニングが終わったとして、実際の判定処理を行う際の入力画像については、次のような前処理を行います。
(1) 画像の周囲を切り落とす。(Cropping)
これは、画像の中央にある物体のみを見て判定するための処理です。Tutorialの例では、32x32の画像に対して、中央の24x24部分を切り出しています。
(2) 画像のダイナミックレンジを平準化する。(Whitening)
画像データはRGBの256階調なので、各ピクセル(の各RGBレイヤー)は0〜255の値で表現されています。これらすべての値の平均 m と標準偏差 v を計算した上で、各ピクセルの値 x を
(x - m) / v
に置き換えます。簡単に言うと、各ピクセルの値を平均 0、標準偏差 1 に平準化します。これにより、画像の明るさなどの違いを取り除いてしまいます。
トレーニング用の入力画像
一方、トレーニングに使用するデータは、次のような前処理を行います。
(1) 画像の周囲をランダムに切り落とす。(Random cropping)
判定処理の際は中央部分を切り出しますが、ここでは、ランダムな場所を中心として切り出します。ある物体が画像のどの部分にあったとしても、物体の種類の判定は変わらないはずです。このような事実をモデルに「教える」ために、1枚の画像から、いろいろな場所を切り出した複数の画像を用意して、これらすべてに同じラベルを与えてトレーニングを行います。
(2) 画像をランダムに左右反転する。(Random flipping)
上記と同じで、物体が左右反転しても、物体の種類は変わらないはずです。左右反転した画像にも同じラベルを与えてトレーニングすることで、このような事実をモデルに教えます。
(3) 画像の明るさとコントラストをランダムに変更する。
これも同じですね。画像の明るさやコントラストが変わっても物体の種類は変わりません。これにより、さまざまな明るさやコントラストの画像について正しく判定できるようになると期待できます。
(4) 画像のダイナミックレンジを平準化する。(Whitening)
これは、判定処理に使う画像と同じ処理です。画像データに限らず、一般に統計処理を行う際の「データの正規化」と呼ばれる処理に相当します。
前処理済みの画像の例
上記の前処理を施した画像のサンプルは、次のようになります。
左端がオリジナルの画像で、その右が判定処理用の前処理を行ったもの、さらにその右に並んでいるのは、トレーニング用にランダムな修正を施した画像群です。
※前処理をしたデータは、値の範囲が0〜255ではなくなっているのでそのまま視覚化することはできませんが、ここでは、適当に0〜255の範囲に再変換して表示しています。
ちなみに
このモデルで「アニメ画像」の分類に挑戦している方々がきっといると思います。アニメ画像の場合、実写画像と比較して、明るさやコントラストは安定しているので、もしかしたら、トレーニングセットの前処理として、(3)の部分(明るさやコントラストのランダムな変更)は無くてもよいかも知れません。前処理の違いによる識別精度の変化について、誰か報告してくれると嬉しいです。