畳み込み後のMNIST画像をExcelに実装したニューラルネットワークで判別してみる。

2024年5月19日

畳み込みした後の圧縮画像をExcelニューラルネットワークで判別してみる

前回は28×28画素の数字画像を畳み込みによって3×3画素の画像に圧縮しました。

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

 

これはただ単に圧縮したのではなく、縦/横/右斜め/左斜めの4種類のフィルターでそれぞれの特徴を抽出してから圧縮したので、特徴量が凝縮されています。

いわば、それぞれの画像の尖ったキャラだけを抜き出したデータということができます。

 

一方前々回は、3×3画素の〇✕画像をニューラルネットワークの誤差伝播法で解くアルゴリズムをExcelに実装しました。

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

そこで、3×3に圧縮した数字画像をこのExcelアルゴリズムに教師データとして投入すれば、数字画像も区別できるようになるだろうと想像できます。

 

今回は、これを試してみます。

まずMNISTの学習用データから「4」と「5」の画像データを5枚ずつ合計10枚抜き出します。

それぞれの画像は28×28画素です。

次に、縦/横/右斜め/左斜めの4種類の5×5のフィルターをそれぞれの画像に掛けて、24×24画素の画像に畳み込みます。

この時点で24×24画素の畳み込み画像が40枚できます。

 

次にそれぞれの畳み込み画像を最大プーリングによって3×3画素の画像に圧縮します。

最大プーリングとは、前回解説したようにいくつかのゾーンに分割して、それぞれのゾーンの中の最大値を取るやり方です。

 

ここまでで3×3の圧縮画像が「4」と「5」について20枚ずつできますので、これらを前々回作った〇✕を見分けるExcelのアルゴリズムに投入するのです。

果たして正解率100%になるように、すべてのパラメータ(重みとバイアス)を調整することができるのでしょうか?

 

畳み込み圧縮データを用意する

今回、教師データとして使うのは次の10枚の画像です。

 

すべて28×28画素の画像です。

それぞれの画像について、次のように畳み込み&プーリング処理をして4枚の圧縮画像を作ります。

そして、教師データを付けます。

「4」が正解であればt1=1、t2=0となるように、「5」が正解であればt1=0、t2=1となるようにt1とt2を定義します。

クリックすると拡大します

 

この前処理をすべての元画像について行えば、「4」について20枚、「5」についても20枚、合計40枚の圧縮データが出来上がります。

 

Excelニューラルネットワークに圧縮データを投入する

次に前々回に〇✕を見分けるために作ったニューラルネットワークを実装したExcelシートに、40枚の圧縮データを入力します。

〇✕の時も3×3の画像で、教師データを表す変数もt1とt2の2つでしたので、そのまま入力できます。

具体的には、下記の位置に数値をコピペします。

クリックすると拡大します

と、このように40枚分のデータをそのままコピペしてもいいのですが、今回は以前の記事で解説した確率的勾配降下法を使ってやってみます。

普通の勾配降下法ではバッチ方式といって、40枚分のデータすべてについての誤差関数を合計して、それが最小になるようにパラメータを調整します。

これに対して確率的勾配降下法では、40枚の中から1枚分のデータをランダムに選んで、パラメータを調整しながら誤差関数を最小化するという計算を逐次的に行う方法でした。

>> 【Excelでアルゴリズムを実装】確率的勾配降下法を使って最小二乗法を解いてみる

 

なぜこの方法を使うのかというと、バッチ方式だとExcelシートを作るのが面倒臭いからです。

単にコピペで試行回数を増やせる逐次方式の方が、Excelに実装するにはやり易いのです。

 

従って、予め40枚分のデータをランダムに並べ替えたデータを大量に用意して、それを上図の位置にコピペしました。

 

学習結果

隠れ層のパラメータが学習されず収束しない

実行してみた結果、初期の正解率が48%で、5,000回くらい学習させた後も48%で全く収束しませんでした。

正解率48%ということは半々ということですので、当てずっぽでやってもこれくらいは当たることになります。

頭の悪いAIです。

シートをよく見てみると、隠れ層H1~H3にかかる重みの勾配が最初からずっとゼロのままでした。

クリックすると拡大します

 

入力が大きすぎシグモイド関数の微分がゼロになることが原因

重みはこの勾配分だけ変化させていくので、勾配がゼロでは重みは初期値からいつまで経っても変わらないことになります。

更に、なぜ勾配がゼロになってしまうのかを追っていくと、シグモイド関数の微分がゼロになっていることが分かりました。

隠れ層の重みの勾配は次式で計算されます。

 

∂E/∂ wH11 =∂E/∂ zH1 ・∂zH1/∂ uH1・∂uH1/∂ wH11

=(∂E/∂ zO1 ∂zO1/∂ zH1 +∂E/∂ zO2 ・∂zO2/∂ zH1)・∂zH1/∂ uH1・∂uH1/∂ wH11

={(zO1-t1) wO11 + (zO2-t2) wO21} f’(uH1)  x1

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

 

赤字の部分がシグモイド関数の勾配で、これがゼロだと全体がゼロになってしまうのです。

なぜシグモイド関数の勾配がゼロにしまうのかというと、uが大きすぎるからです。

クリックすると拡大します

 

入力データを一律1/1000倍して解決

更になぜuが大きくなるのかというと、入力xiもしくは重みwijが大きすぎるからです。

重みwijの初期値は0から1の乱数で決めましたが、入力xiは圧縮データですので1,000以上の値もあります。

従ってuの値も1,000以上になってしまうのです。

これを避けるには入力xiを小さくすればいいので、一律1/1000倍しました。

 

5,160データを学習して収束

このような対策をした結果、5,160データを学習したところで収束しました。

収束条件は40データ連続して正解になることを条件としましたので、これ以降も更に誤差関数を小さくするためにパラメータの更新はされているのですが、以降は正解率が100%を下回ることはありませんでした。

クリックすると拡大します

 

教師データ以外の画像で検証してみる

以上で教師データはすべて正確に見分けられるようになりましたが、別の人が書いた数字を見分けらるかということは別問題です。

次の4枚の画像で確かめてみましょう。

 

学習後のニューラルネットワークで、これらの数字を見分けられるかを調べてみましょう。

まずは学習データと同じように4つのフィルターを通して畳み込みし、その後3×3に圧縮(プーリング)します。

 

そしてプーリング圧縮後のデータを学習後のExcelニューラルネットワークに入力値として投入します。

結果、すべて正確に見分けられたのですが、一つだけ例として一番難しそうな最後の「5」についてExcelシートをお見せします。

クリックすると拡大します

 

このように4枚の圧縮画像すべてについて「5」と判定しました。

実際に計算された確率も見てみましょう。

クリックすると拡大します

 

最初と最後の画像は95%くらいの確信度で「5」と判定していますが、2番目と3番目の画像は67%くらいの確信度しかありません。

ニューロ君も相当悩んだ様子が伺えます。

どれだけ難しかったのか、2番目の画像で見てみましょう。

2番目の画像は縦の線を検出するフィルターで畳み込んだ画像です。

他の3枚の「5」の画像と並べて、この「5」がどれだけ特殊かを比較してみましょう。

クリックすると拡大します

 

普通の人が書く「5」は左上と右下の2か所に縦の線がきます。

しかし左上の画像だけは真ん中に集中しています。

これが正に今回ニューロ君が悩んだ画像です。

これだけ崩されると無理だろうと思ってしまいますが、ニューロ君は何とか「5」と判定しています。

 

ちなみに、ニューロ君は元の「5」の画像は知らずに、この3×3の圧縮画像だけで「5」と判断しています。

もはやどうやって解釈しているのか人間には理解できません。

これがニューラルネットワークの凄いところであり、怖いところでもあります。

 

尚、今回は特徴を抽出するためのフィルターを、管理人が縦/横/右斜め/左斜めというように設定しましたが、本来はニューロ君がこれを決めます。

こんな単純な形ではなくて、もっと複雑だけれども特徴をよく表す形のフィルターを自分で決めるのです。

益々、凄いですね。

 

しかし、これをExcelで実装しようとすると、畳み込みの部分まで誤差伝播法で遡って勾配を計算する必要がありとても複雑になってしまいます。

この検証は暇で暇でどうしようもなくなったらしようと思います。