【中学数学で理解する】畳み込みニューラルネットワークの原理をわかりやすく

前回は3×3の9画素で〇✕を見分けるニューラルネットワークを作りました。

>> ニューラルネットワークを使って画像処理する方法をExcelでわかりやすく解説

 

単純化した例だったため、チューニングすべきパラメータ(重みやバイアス)も38個と少なく、教師データは44枚で学習できました。

しかし現実に手書き文字を見分けようとするともっと画素数が必要で、パラメータ数も飛躍的に増加します。

教師データはパラメータ数以上は必要なため、教師データを揃えるだけでも一苦労です。

 

MNISTをダウンロードする

ありがたいことにネット上にはニューラルネットワークの学習用の教師データとして、いろいろなデータがアップされています。

その中の一つに、MNISTという手書き文字の教師データがあります。

MNISTとは、NIST(National Institute of Standards and Technology、アメリカ国立標準技術研究所)が出している手書き数字の画像データ集です。

手書き数字を28×28画素に分け、それぞれの画素の輝度(明るさ)が256段階で表示されています。

例えば次のような感じです。

 

薄っすらと「4」の文字が浮かび上がっています。

更によく見ると、数字の箇所には0以外の数字が入っており、これが輝度を表します。

輝度の高い画素を黒く、低い画素を白く数字に比例させて表示させると、次のようになります。

 

このように、28×28の画素数でもまだ粗いため、完全に塗りつぶされていない画素には256ではなく、100などの小さな数字が塗りつぶされている割合に応じて入っています。

 

このようなデータが学習用mnist_train.csv)に60,000枚、検証用mnist_test.csv)に10,000枚用意されています。

数字の種類は0から9までなので、1つの数字につきそれぞれ6,000枚と1,000枚の手書きデータが収められていることになります。

このファイルはこちらからダウンロードできます。

>> mnist-csv-png (github)

 

ダウンロードして開くと、csvファイルですので数字の羅列になっています。

 

1つの数字に付き1行で、先頭は正解データ、続く784個(28×28)は輝度データになっています。

これを先ほどのような28×28のデータに並び変えるには、次のようなマクロを組めば”Sheet1”に書き出されます。

(60,000行と長いため、最初の200行だけ書き出しています)

 

畳み込みは中学数学で理解できる

さて、MNISTのデータを使って前回作ったExcelファイルで学習させようとすると、いくつかの問題が生じます。

各重みの勾配を計算するための誤差伝播法は入力データが大きくなっても汎用性はあるのですが、パラメータの数が多すぎてExcelシートが膨れ上がってしまうのです。

1画像につき784画素のデータがあるため、隠れ層に3つのユニットがあるとすると、それだけで784×3=2,352個のパラメータが必要になります。

これだけの大きさのExcelシートを作るのは、いくらマメな管理人でも嫌気がさしてしまいます。

そんな時に役に立つのが畳み込み(Convolutional Neural Network、CNN)です。

必要な情報を濃縮しながらパラメータ数の圧縮ができます。

難しそうに思えますが、中学数学で理解できます。

どのような仕組みか見てみましょう。

 

先ほどの28×28画素の「4」の画像を、5×5の大きさのフィルターを通して見ることを想像して下さい。

このフィルターは真ん中の1行だけ穴が開いているこんなフィルターです。

 

このフィルターを下図の①~③の位置に重ねてみましょう。

 

真ん中の数字の行しか見えませんね。

つまり、このフィルターは真ん中の行だけを抜き出すフィルターです。

 

これを数学的に表すには、次のように真ん中の行だけ1が入っていて、残りは0が入っている行列を使います。

 

これだけでは何も起こりませんので、フィルターを重ねたら行列の各成分同士を掛け合わせます。

すると25個の数字ができますので、それらを合計します。

すると、フィルターは真ん中の行以外の成分は0ですので、何を掛けても0のままです。

対して、真ん中の行の成分は1ですので、元の画像の対応する成分がそのまま足し合わされます。

これが、先の図で赤字で行っている計算です。

 

このように計算すると、①の箇所ではフィルターを重ねると0しか見えませんので、フィルターを重ねると0が帰ってきます。

②の箇所では0、121、231、0、0が見えますので、121と231を足した352が帰ってきます。

③の箇所では同様の計算によって1,253が帰ってきます。

 

この数字は何を意味しているのでしょうか?

そうです、細い横長の線が含まれる度合を表します。

この数字が大きいほど横長の線が含まれる度合が大きいことを意味します。

これは感覚的にもわかりますね。

 

もう一つ違うフィルターでも見てみましょう。

このような斜めのフィルターを通して見ると、斜めの線が多く入っている箇所では大きな値が帰ってくることがわかると思います。

 

このように取り出したい形のフィルターを隅から隅までスキャンしていけば、どの場所にその形が多く含まれているかがわかります。

ですので、次のように端から一つずつずらしながらスキャンしてみましょう。

フィルターの形は最初に出てきた横線を取り出すフィルターだとします。

 

横に24スキャン、縦に24スキャンの合計24×24=576スキャンすることになりますので、576の値ができます。

それを並べると次のようになります。

 

値が大きいほど黒く塗りつぶすようにしていますので、横線がある密度が高い箇所が黒く浮かび上がってきます。

真ん中より少し下で、少し左よりの位置に横線の密度が高いことが分かります。

 

次に斜めの線を取り出すフィルターでスキャンするとどうなるでしょうか?

 

真ん中とそこから左よりの位置に斜め線の密度が高いことがわかります。

このように、「4」の字を特徴付けるような形がどの位置によく現れるかを調べることで、「4」の字を見分けることができそうです。

 

しかし人によっては次のように「4」を書く人もいます。

 

この人は先ほどの人より横の線が上の方にあります。

このように人によるばらつきを考慮すると、あまり正確に横線の位置や斜め線の位置を調べても、判断材料として使えない可能性があります。

あまり細かく調べても意味がないということです。

そこで、このスキャン後のデータを更に圧縮します。

圧縮の仕方はいくつかのゾーンに区分けして、それぞれのゾーン内で一番大きな値を取ります。(平均を取るやり方もあります)

例えば縦3、横3の合計9ゾーンに分ける場合は、次のようにします。

 

 

値が大きなセル(画素を表す)は黒く塗りつぶされていて数字が見えませんが、とても大きな値が入っています。

このようにすることによって、どちらの「4」も真ん中の左よりの位置に横線の密度が多いという特徴があることがわかります。

 

ニューラルネットワークでは、教師データからこのような最大公約数的な特徴を数字ごとに抽出します。

そしてどの特徴が重要で、どの特徴がそれほどでもないかを重みによって調整します。

この重みを調整するのは勾配降下法などの難しい計算が必要になります。

 

しかし、その前処理で最大公約数的な特徴を効率よく抽出するための方法は上記の通りで、掛け算と足し算だけでできてしまいます。

ちなみに、最初にフィルターでスキャンすることを畳み込み、その後、ゾーンに分けてゾーンごとに最大値を取ることをプーリング(Poolingと呼んでいます。