Pythonで自分用のAIを作ろう8-教師なし学習(主成分分析) | グラ山ギターのブログ

グラ山ギターのブログ

毎週健康のために山登りをしています。低い山ばかりですが播磨の山々は岩山が多く景観がすばらしい所が多いです。山頂などで演奏しています。 井上陽水のカバーが多いです。
暑い時期は山登りは控えています。

Pythonで機械学習やディープラーニングをやる前に、少し基礎的なことを理解するために整理する。(独学のため、大学の先生方から見て誤解している箇所があるかもしれませんが、大目にみてください。)


AIの学習方法には教師なし学習と教師有り学習がある。

30年程昔に私が画像認識に2年間だけ取り組んだ際に、画像特徴から物体を認識するために、画像特徴は、種々のエッジ特徴や図形のモーメント等、人間が画像からこのように計算した特徴というものを用いて、これは顔であるこれは顔以外の時の特徴という学習データを準備して、機械学習させていた。これは教師有り学習と呼ぶもので、現在では識別器の学習に用いられている。
原始的な特徴で、良い特徴を選定していないと、いくら学習を丁寧にやっても最終の識別器の性能がなかなか向上しないというジレンマによく陥った。

 

 現在のディープラーニングでは、この原始的な特徴を選ぶのに教師なし学習が用いられ、うまく行っている。人間が選んだ特徴量より、大量のデータから教師なし学習で得た特徴の方が性能が良いらしい。
2012年に発表されたHinton先生の「ImageNet Classification with Deep Convolutional Neural Networks」と題したディープラーニングの論文では、従来の機械学習による画像認識にくらべて深層学習が圧倒的な認識性能をもつことが示された。

 

論文で発表されたディープラーニングは7つの隠れ層があり、5層のconvolution層はRBMを重ねて、Maxpoolingで情報削減する構成になっており、この5層で事前の教師無し学習を行い、そのあと、教師有りデータで残り2層の全結合層を含めた7層でディープラーニングを行うというものでした。これにより2011年ではご認識率が26%だったものが16%まで大きく改善されたことで、一躍ディープラーニングが注目されたということです。
第1層で学習された画像特徴が掲載されていました。
では、教師無し学習にはどのようなものがあるのか?
主なものとして下記のものがあげられる
1.クラスタリング k平均法 k-means++法
2.主成分分析法(PCA: Principle Component Analysis)
3.独立成分分析法
4.スパースコーディング
5.RBM(Restricted Boltzmann Machine)
 
このうち、2.主成分分析法(Principle Component Analysis:PCA)は古典的ではあるが、変換ー逆変換の概念が判りやすいので、今回は主成分分析法について紹介する。
まず、主成分分析法の解説に入る前に、良く知られているフーリエ変換の性質について復習しておこう。
音を時間軸にサンプリングしたデータを離散フーリエ変換(DFT)をすると、周波数成分が取り出せる。逆にフーリエ変換成分を逆変換するともとの時間軸データに戻すことができる。時間軸ではサンプリングデータであるが、フーリエ変換をすると、sin(nθ)やcos(nθ)等の互いに直交する関数で展開することができて、元のサンプリングデータは直交関数にある係数aiを掛けてΣをとったもので表せます。
フーリエ変換の場合は各固有関数e-i(2πkn)/N(基底関数とも呼ぶ)が直交するので、x0~xN-1がX0~XN-1に変換したり、逆変換X0~XN-1からx0~xNのいずれも完全に変換することができます。この場合はN個のサンプルデータからN個の周波成分になるので、いずれの変換も情報は全く失われません。
しかし、音声信号の場合、時間軸のサンプル数Nに対してフーリエ変換後のX0~XN-1のうちいくつかの成分が0になるような信号があります。この時は、フーリエ変換することで、N個のデータより少なくなるので、情報を圧縮することができます。圧縮したデータでも逆変換するとN個のデータを復元することができます。
主成分分析は、種々の母集団の統計的性質より、基底となる直交関数を求め、総分散に寄与する成分だけで合成できるようにするものです。変数がxi(i=1~n)としてそのバラツキや平均値から変数yiに変換する。新しい変数zj = Σaijyi と定義し、Σaij^2=1という拘束条件のもとで、分散U(a1j,a2j・・amj,λ)=ΣΣakjaljSkl +λ(1-Σakj^2)が最小となるaijを求める。
この問題はyiの分散行列の固有値問題となる。
実際の画像を用いて主成分分析を行ってみる。もとの画像が662x525画素の画像を16x12の40x42ブロックに分割した。1つのブロック16x12画素を1列の192画素とみなしてこれをxiベクトルとする。

i=1~1680である。xiベクトルの平均値xb = Σxi/n, σ=Sqrt(Σ(xi-xb)^2/N)で求め、yi=(xi-xb)/σで正規化する。yiの分散行列S1を求め、S1の固有値および固有ベクトルを求める。
固有値の和は分散行列S1の対角要素の和と等しいので、固有値の大きい順に40個をとり、それに対応する固有ベクトルも計算する。
固有値の内大きい順に40個を選べば、寄与率は0.999961なので、ほとんど情報が欠落していないことになる。1ブロック16x12画素=192個のデータが40個の独立するデータで表現できたということで、情報の圧縮になっており、結局のところ教師無し学習は情報圧縮と等価である。
固有値に対応する固有ベクトルは直交するので、情報圧縮だけでなく逆の復元も容易である。
次に8人x10枚の顔画像について主成分分析する。
原画像
固有ベクトル
この顔画像の場合、80枚の画像で79個の固有顔にしか情報が削減できなかった。これはいきなり顔の色々な向きの画像を学習させたのでそれだけ独立した情報が必要ということになる。
顔の場合はエッジ成分のような小さい特徴、目や鼻等の中程度の大きさの特徴、顔全体等の大きな特徴別にデータを圧縮させる必要があり、2012の論文のように、1層2層3層と小さな特徴、中程度の特徴、大きな特徴が学習できる構造は、画像認識にとって非常に有効なのだと感じた。
今回はPythonではなくMathematicaでのコーディングで主成分分析をおこない、原理面の理解を深めてみた。