content合理と非合理のあいだ人工知能・哲学・スタートアップについて綴ります。今回は「ニューラルネットワークは何故多層なのか」つまり「多層であると何が嬉しいのか」という問と絡めて、手書き文字認識を例にまとめてみる。この記事は技術者&非技術者向けであるが、一応ニューラルネットワークとは何かと、その基礎構造を知っていることを前提にしている。NNまず、NNが一層だけ(隠れ層なし)だった場合を考えてみる。MNIST手書き文字認識では、28×28の画像(グレースケール)のピクセルを左上から右下まで一列に並べた784個のピクセル列(たとえば真っ白が1,真っ黒が0などと表されている)とバイアス項を入力とし、10個の出力(それぞれが0〜9の数字に対応、重みと入力の積が大きかったクラスの数字と識別)を持つ。入力ノードはすべての出力ノードとつながっているので、図([3]より引用)の矢印の部分には、実際には7850本の矢印がある。NNでは、その7850本の重みをデータからトレーニングする。「0」という出力ノードにつながった785本の重みは、「0っぽい画像」が来た時に0の出力ノードの値が他のノードよりも大きくになるように鍛えられていなければいけない。ヒントンダイアグラムは、ある特定のノードにつながった重みだけを取ってきて、それを可視化する(上図参照)。白は正の値、黒は負の値、セルの大きさは(相対的な)絶対値を表す。出力ノード0につながっている重みを可視化したヒントンダイアグラムは上のようになる。白の部分が正値なので、白い部分の入力が多い画像ほど0に分類されやすくなる。なんとなく0っぽい形をしていることがわかる。他の出力に関しても、ヒントンダイアグラムは同様にそのクラスの数字のぼんやりとした輪郭になる。NNの場合、イメージとしては、このヒントンダイアグラムの描かれた紙を10枚重ねあわせ、入力画像と照らし合わし、入力画像の黒インクとヒントンダイアグラムの白い部分が重なる面積が一番大きいクラスを選ぶというアルゴリズムになる。NNは、テンプレートマッチングに等しい。各クラスはただひとつだけのテンプレートを持ち、それとの近さで入力画像のクラスを判別する。隠れ層を挟んでみるテンプレートマッチングはシンプルだが、実際のデータはゆがみや大きさの違いや回転や平行移動があり、「0の形」をしていてもそういった違いのせいでテンプレート自体は「8」に近づくなどという事が起こる。単純な解決策としてテンプレートを増やす、つまり例えば出力ノードを10個から100個にし(各クラスが10個のテンプレートを持つ)1〜10個めに分類されれば0、2〜20個に分類されれば2...というようにネットワークを横に広げる、ということが考えられるが、これはあまり良い策ではない。数字の形のパターンは当然10個以上あるし、数字ならまだしも人の顔などとなればテンプレートは無限に必要だからだ。そこで、人類はネットワークを縦に伸ばすことを考えた(上図ー[3]より引用)。これはテンプレートの数を増やすのではなく、テンプレートをパーツに分けるすることに対応する。そのパーツを一般に「特徴」と呼ぶ。(だからテンプレートもまた定義上は「特徴」であり、ピクセルもまたもっとも細かい「特徴」なはずなのだが、それらを特徴として特別視することに何の意味もないので、慣習的にはそれらを特徴とは呼ばない。)ちなみに、図では領域ごとに分割されているが、レイヤーを増やしたからといって別に領域ごとの特徴を捉えられるわけではない。実験してみる実際にどんな特徴が抽出されるのかを、28×28のMNISTデータとpythonを使って実験してみた。隠れ層は一層のみでノード数は100個のネットワークモデルを使って、実際に重みを描画してみるという実験を行った。(ちなみにこれはエディンバラ大院のDeepLearningの授業の宿題のひとつだ)実際の結果が以下のようになった。各画像は28*28で、それぞれが隠れ層の100個のノードのうちの一つに対応している。左上が1個め、右下が100個目の隠れノードである。(これはヒントンダイアグラムではなく、重みの値をただ描画したものだ。本の枝をすべて描画しており、画像内の1個のピクセルが重みの枝一本に相当する。ひとつひとつのノード(特徴)が特定の数字を表しているのではなく、それらのパーツを表していることがわかる。2層NN(隠れ層1層)の場合、出力をこれら100個の特徴の組み合わせで表現するようなイメージだ。組み合わせれば無限にテンプレートが作れるので、テンプレートをたくさん用意するよりずっといい方法だということがわかるだろう。次は、その1層上(出力層)を描画してみる。先ほどの1層のNNの例と似てるが、今回は層が2つあるため出力層を直接描画することはできないので、下図でつながっている部分の2つの重み(出力ノード0と隠れ層間の重みと、隠れ層間と入力層間の重み)を掛けた重みを描画している。(1×100行列と100×784行列の積=1×784ベクトルを28×28に描画)0の出力ノードに対応する描画結果は以下のようになった。(ついでにヒントンダイアグラムも)結果自体は1層の例と似ているが、今回は2つの重みの行列積を描画していることに注意されたい。このようにしていけば、多層になっても中間層のノードの特徴を入力と同じ次元で描画することができる。1層目は数字の特徴(パーツ)を表現していたのに対し、2層目は数字を表現している。出力層に近い層ほどその層はマクロな特徴を表現する重みを持っていて、入力層に近いほどミクロな特徴を表現するということになる。なるのか?という問へは、(おそらく)解析的にはわからない。ランダムな値から出発して、バックプロパゲーション(誤差逆伝播)を使って重みをトレーニングしていった結果、重みがそんなふうになってしまったのだ。イメージとしては、1枚目の隠れ層はピクセルを入力としているが、2枚目の隠れ層は1枚目の隠れ層(つまり各特徴がどれくらい強いか)を入力としているので、その特徴の組み合わせから成る特徴が表現されるのが自然、だと考えることができる。上が出力層なのを考えれば、上のような層ごとの段階的な表現は理にかなっている。ションを行えば、その入力を、その層の特徴のベクトル表現として表せる。元の特徴ベクトルで表現できる。これが特徴職人が必要なくなったと言われるゆえんだ(と思う)。まとめ手書き文字を構成する線のパターンは限られているので、それほど深層化(実際隠れ層1層だけでも90%以上の精度が出た)させる必要は無いが、例えば下のような([2]より引用)顔の識別の場合、画像を特徴づけるパターンは手書き文字よりも格段に多いので、単に隠れ層のユニット数を増やす(ネットワークを横に広げる)よりは層を増やしたほうが有効そうだ。層を増やせば増やすほど正確になるというわけではない。gradient問題が発生してプリトレーニングが必要になったりと、時に面倒は増える。闇雲に深層化させるのではなく、ハイパーパラメータの調整とかユニット数の調整など、問題に応じて対応しなければいけない。コメントをキャンセルメールアドレスが公開されることはありません。