こんにちは、ニューラルネット老人こと糟谷勇児です。
今回は色について考えていきます。
色を扱うのは難しい
画像認識といえば色の活用が重要そうですが、実際は一筋縄ではいきません。
私が新入社員だったころのことです。
中国人の先輩が画像検索エンジンを作っていました。その際、色は使用せず、輝度の変化のみを使用していました。
私は「色は使わないんですか」と尋ねたところ、「Color is artificial」という答えが返ってきました。
なるほど、色の見え方は人間とそれ以外の動物では全然違うといわれています。
もちろん人間同士でも、人種や性別、色覚特性などによって色の見え方はかなり変わってきます。
色というものは人間の感性に大きく依存するもので、独立した物理現象としてみるのは難しいのかもしれません。
前職の別の案件で、顔検出を行う際に肌色領域に絞ることで高速化できないのかという検討が行われたことがありました。
ただそれも結構難しかったようです。肌色といっても人種ごとに異なるし、環境光に強く影響を受けます。
例えば、水族館で青い光に照らされた肌色は青くなります。
環境光の影響を取り除くような画像処理も考えられますが、高速化という観点ではより時間がかかってしまいます。
色空間
画像の色を扱うとなると、色空間の選定は重要です。
というのもRGBという光の三原色であらわされた色空間は人間の感じる色同士の距離と合っていないからです。
ペイントの画面で作った例を出します。
上は灰色同士です。左の色と右の色の間のRGB色空間上のユークリッド距離は86、下は黄色と緑色の比較ですが、ユークリッド距離で80です。
同じ80の距離でも灰色同士だと似たような色に見え、緑と黄だと全然違うように見えないでしょうか。
色の話になると、人間は明るさはあまり重視せず、色合いや鮮やかさを重視する傾向があります。
そこで、人間の知覚に近い色空間がいろいろ提案されています。
私はLab色空間が好きでよく使っていました。
Lは輝度、a,bは色の成分です。
さて話をニューラルネットに戻します。
色空間のどれを使うかというあたりで技術者の個性も出る感じだったのですが、ディープラーニングではRGBをそのまま使うのが主流と聞きちょっと驚きました。
今回はそのあたりも含めてみていきましょう。
M対Nのコンボリューション
以前実装したLeNetではグレースケール画像を前提にニューラルネットワークが作られていました。
最初は1平面の画像を、5個のフィルタで、5平面の画像にします。
もちろんこの時、3平面のRGBの画像を入力することも考えられます。
そうすると同じ5個のフィルタでも3×5で15平面の画像ができてしまいます。
さらに次の層では5個のフィルタで増やすので75平面の画像ができますが、ちょっと多くて時間がかかりそうですよね。
LeNetでは2回目のコンボリューション層でいくつかの画像を合体させて、平面数を減らす工夫が行われています。
これを使って1層目から減らしてもいいですが、どう組み合わせるのがいいのか設計がいろいろ難しいですね。
そこで、現代のコンボリューショナルネットでは3平面の画像を5平面にしたいときは、3×5の全パターンのフィルタを作って計算し、合体させるということをします。
以前紹介したAlexNetもその方法を用いているようです。
計算方法は、このブログを参考に実装させていただきました。
qiita.com
イメージ図で書くとこんな感じです。
行列の要領で、上図のfb1を画像のB(青)の成分に、fg1を画像のG(緑)の成分に、fr1を画像のR(赤)の成分にそれぞれ適用して出てきた画像を足し合わせたものが、一つ目の平面になります。
これなら5を7にするのも、10を3にするのも、どんな平面数の組み合わせでも実現できます。
しかし、一見するとすごく時間がかかりそうです。
実際、5個のフィルタで1平面を5平面にしていた時と比べて、3倍時間がかかりはします。ただ、そこから先の時間はあまり変わらないので、ほとんど同じ時間で実行することができます。
バックプロパゲーションの計算もより素直な感じになります。
これまでは5つのフィルタを5平面の画像にかけると、ある1つのフィルタが5平面の画像を作り出していました。
なので、複数の画像から逆伝搬してくる信号を足し合わせる必要がありましたが、このM対Nの方式では一つ一つのフィルタは一つの画像を作るのにしか使わないので足し合わせる必要がなくなりました。
そのため、バックプロパゲーションの計算時間は実はほぼ変わりません。
さて、これで原理的には色を学習するようになるはずですが、本当に色に反応するフィルタはできたでしょうか。
いつものようにC#で実装して実験してみましょう。
実験
LeNetの1層目と3層目を今回作成した、M対Nのコンボリューションに変えてみます。
今回は1層目のフィルタのサイズを5×5から7×7にしてみました。
7×7×3×5なのでパラメーター数は735になります。
全パターンのフィルタを作るというと、力技に感じましたが、32×32の画像をニューロン数100の全結合層で扱うとすれば、パラメーター数は10万を超えますから、そこまででもないのかもしれません。
扱う問題はこれまでと同様、cifar10の船と飛行機を見分ける問題としています。
船
vs
飛行機
意外と夕焼け背景が多め。色ですぐ区別がつくかというと難しそう・・・
前回と同様にフィルタをエクセルで見てみます。
だいたいは、RGBの各平面に対して同じようなフィルタが得られているのですが、一つだけ違うのもありました(下図の左)。
4番目のフィルタは青の成分に適用するフィルタのみ大きく変わっています。
主観的に解釈してみると(図の右)、フィルタの左側はB成分のみが高い状態に反応する、つまり青に反応し、真ん中では全成分が高い状態、つまり白に反応し、右側では全成分が低い状態。つまり黒に反応する、そういうフィルタができていました。
海の青、船体の白、黒いエッジに反応するような感じでしょうか。興味深いですね。
このコンボリューショナルネットは87.7%の精度となったので、いつもよりちょっとだけ精度が上がったかなという感じです。
テストデータは1000枚でやっているので+7枚ぐらい。
残念ながら、船も飛行機も背景は、海や空で物体は白やグレーとあまり色には違いがないんですよね。
そこで、色が全然違うcifar10の鹿と船の画像を判別する問題にしてみました。
鹿
とはいえ、こちらも収束が早めなことと、最大値ではRGBが勝っているものの、誤差の範囲かなといったレベルでした。
色が全然違うレベルの場合、輝度だけで見ても全然違うので、色のありなしで大きく向上する例はなかなかないかもしれません。
色を扱うのはやはり難しいですね。
さて、これまでRGBの色空間で画像を入れてきましたが、最初に書いたようにRGBは人間の知覚と近いかといわれると、そうでもないという問題がありました。
ではLab色空間に変換してみるとどうか・・・
まずは鹿と船の画像をLab色空間に変換して学習させてみます。
OpenCvのcvtColor関数を用いて変換したので、Labそれぞれ最小値は0最大値は255です。
結果はこちら。
大幅に精度が下がってしまいました。二乗誤差もあまり下がりませんでした。
ここからは私の考察です。
画像を認識する際に色の貢献はそこまで重要でないと考えたときに、重要な輝度の情報に1平面のみ割当て、あまり重要でない色の情報に2平面割り当てているので、重要でない情報がより多い状態から学習がスタートすることになります。
ニューラルネットは局所最適解に陥りやすいので、色を重視した状態のまま、学習が進まなかったのかもしれません。
そこで、Labのa,bの成分を10分の一にして入力してみます。
つまり0~255ではなく、0~25.5に変わります。
この場合、初期の影響度は輝度成分が5倍ということになります。
そうすると、RGBと同じように学習ができ、精度は少し低いながら、二乗誤差は同じぐらい少なくなりました。
結果はこちら。
色を使うことで過学習が起こっていることは否めませんが、Lab色空間でも学習することはできたようです。
とはいえ、1/10にするのが最適なのかもよくわからないですし、Labではなく他の色空間が最適なのかもしれません。
そう考えていくと、RGBをそのまま入れることは、色と輝度をあまり分離せずに使用することができ、ニューラルネットではベターな解であると言えそうです。
ただし、それも問題次第かもしれません。写真(自然画像)の認識とロゴマークのような人工の画像の認識では状況は変わってくるかもしれません。
また、RGBと他の色空間を両方入れるというやり方もあるようです。
mocobt.hatenablog.com
これなら色成分だけに多数の次元が割り当てられてしまう状況は緩和できますね。
次回は
今回はM対Nのコンボリューションを扱ってきました。
M対Nのコンボリューションを作ったことで、当初目標としていたAlexNetへの道筋も見えてきました。
とはいえ、まだ未実装の要素もいくつかあります。
AlexNetでは最終層がSigmoidではなく、ソフトマックス層を用いています。
dropoutやdata augumentationもまだ未検証です。
次回はこの辺りの要素を実装して、ついに2012年の技術に追いついていこうと思います。
▼本シリーズのほかの記事はこちら