ニューラルネットワークをExcelに実装して画像処理させてみた。
9画素のマークシートに書かれた〇✕をニューラルネットワークで読み取る
入学試験や運転免許証の試験などで、誰でも一度はお世話になったマークシート。
大量の答案を機械で自動処理できることが魅力です。
このマークシート、昔はOMR(Optical Mark Reader)という専用の機械で処理していました。
ところが、そのためには専用の答案用紙や読み取り機が必要になりコストが嵩むため、最近では一般の用紙を使って汎用のコンピュータで処理できるスキャナー方式が普及してきています。
スキャナーとは、手書きなどのアナログデータをコンピュータで処理できるデジタルデータに変換する装置です。
コピー機やプリンターに付いていますね。
ところで、スキャナーの読み取り精度は画素数に依存します。
〇✕式のマークシートを読み取るには最低9画素は必要でしょう。
回答者には、○を書くにしても、×を書くにしても枠一杯に書いてもらうようにします。
すると○の場合、理想的には次のようになります。
9個の画素のうち、線を検出した画素には1、そうでない画素には0が入ります。
この1と0のパターンを見て、コンピュータは○か×かを判定します。
でも、こんなきれいな○を書く回答者はいないでしょう。
実際には、こんな感じになります。
これだって、ほぼ理想的なケースです。
人によっては筆圧が小さかったり、○を書きだす位置が異なっていたり、途中で芯が折れたりして、様々な欠損があるでしょう。
例えば、こんな感じです。
これも○と読み取らないといけません。
でも、×はもっと厄介です。
理想はこうです。
しかし、こんなにきれいに書ける人は稀でしょう。
実際にはこんな感じが多いのではないでしょうか。
このように○にも×にも、いろいろなパターンがあります。
9画素の1と0の組み合わせは、29=512通りあります。
たった9画素でも512通りものパターンがあるのです。
実際には遥かに多くの画素数で読み取りますので、天文学的なパターン数になります。
ですので、すべてのパターンについてこれは○、これは×という風にコンピュータに設定しておくことは現実的ではありません。
そこで、これまでの回答者から集めた○×のパターンをコンピュータに学習させて、今後違うパターンが出てきたとしても適切に○×を自動判別させる仕組みが機械学習です。
そして、このような画像処理はニューラルネットワークが得意で、前回の記事で紹介した誤差伝播法を使ってプログラムすることができます。
>> 【実はとても簡単だった!】誤差伝播法をシンプルにわかりやすく解説します。
これをExcelに実装してみましょう。
Excelが学習していく様子は、まるで生き物みたいで結構感動的ですよ。
教師データを用意する
まずコンピュータに教え込むための教材を用意する必要があります。
この教材を教師データといいます。
今回は次のようなデータを用意しました。
○、×ともに22パターンあります。
ニューラルネットワークにモデル化する
入力層は9つ、出力層には2つのノードを割り付ける
次に、この画像処理をニューラルネットワークにモデル化します。
ニューラルネットワークには入力層、隠れ層、出力層の3層がありましたね。
前回の記事では入力層に2つ、隠れ層に3つ、出力層に2つのノードがあるネットワークで説明しました。
>> 【実はとても簡単だった!】誤差伝播法をシンプルにわかりやすく解説します。
まずは、それぞれの層のノードに何を割り付け、合計でノードがいくつ必要になるのかを決める必要があります。
今回のケースでは何を入力層に割り付ければよいでしょうか?
9つの画素の二値データですね。
9つの画素はそれぞれ0か1の値を持ちますが、それぞれをx1、x2、、、x9とします。
次に出力層には何を割り付ければよいでしょうか?
今回は○の確率と×の確率を出力したいので、それぞれ1つずつ出力を割り付けましょう。
O1に○と判断する確率が入る変数、O2には×と判断する確率が入る変数を割り付けましょう。
最後に隠れ層ですが、これは設計者が割り付けるのではなく、アルゴリズムが決めることなので分かりません。
とりあえず3つのノードにしておきます。
以上を図で表すと次のようになります。
活性化関数にはシグモイド関数
ここで一つ注意点があります。
前回の記事では活性化関数をf(u)=uという恒等関数にしていました。
そうすると、説明が簡単になるからです。
今回は出力として確率を求めますので、0~1の数字にするためにシグモイド関数を使います。
活性化関数でよく使われるシグモイド関数の歴史や定義について調べてみた。
この記事にあるように、シグモイド関数f(u)を微分すると
f’(u)=f(u){1-f(u)}
というように、わざわざ微分を計算しなくても元の関数で表すことができます。
これはプログラミングする上で大変便利です。
パラメータの初期値を入力する
求めるパラメータは38個
さて、これからいよいよ各パラメータ(重みとバイアス)を求めていきます。
求めるべきパラメータは、次のように38個あります。
ノードH1の重みとバイアス
wH11, wH12, , , , wH19, θH1
ノードH2の重みとバイアス
wH21, wH22, , , , wH29, θH2
ノードH3の重みとバイアス
wH31, wH32, , , , wH39, θH3
ノードO1の重みとバイアス
wO11, wO12, wO13, θO1
ノードO2の重みとバイアス
wO21, wO22, wO23, θO2
まずは、これらのパラメータと教師データをExcelシートに入力します。
教師データは入力xi(i=1~9)とtj(j=1,2)の組み合わせが44組あります。
これらを順々に行を変えて学習させていって、44組全部終わったら、また1組目から学習させます。
これを延々と何巡も繰り返します。
パラメータの初期値は0~1の乱数
38個あるパラメータ(重みとバイアス)は、まずは初期値をテキトーに決めて、勾配降下法により少しずつ調整していきます。
上の図では、初期値は0から1の乱数としています。
初期値の次からのデータは空欄になっていますが、これから式を入れていきます。
誤差伝播法の計算式を入力する
次に誤差伝播法の計算式を入力していきます。
前回の記事より、各パラメータの勾配は次のような式で求められます。
まずは出力層の勾配、次にその値を使って隠れ層の勾配を求めます。
出力層の勾配を求める計算式
∂E/∂ wO11 =∂E/∂ zO1 ・∂zO1/∂ uO1・∂uO1/∂ wO11
= (zO1-t1) f’(uO1) zH1
ここで、f’(uO1)はシグモイド関数f(uO1)の微分です。
∂E/∂ wO12 =∂E/∂ zO1 ・∂zO1/∂ uO1・∂uO1/∂ wO12
= (zO1-t1) f’(uO1) zH2
∂E/∂ wO13 =∂E/∂ zO1 ・∂zO1/∂ uO1・∂uO1/∂ wO13
= (zO1-t1) f’(uO1) zH3
∂E/∂ wO21 =∂E/∂ zO2 ・∂zO2/∂ uO2・∂uO2/∂ wO21
= (zO2-t2) f’(uO2) zH1
∂E/∂ wO22 =∂E/∂ zO2 ・∂zO2/∂ uO2・∂uO2/∂ wO22
= (zO2-t2) f’(uO2) zH2
∂E/∂ wO23 =∂E/∂ zO2 ・∂zO2/∂ uO2・∂uO2/∂ wO23
= (zO2-t2) f’(uO2) zH3
隠れ層の勾配を求める計算式
∂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
∂E/∂ wH12 =∂E/∂ zH1 ・∂zH1/∂ uH1・∂uH1/∂ wH12
=(∂E/∂ zO1 ・∂zO1/∂ zH1 +∂E/∂ zO2 ・∂zO2/∂ zH1)・∂zH1/∂ uH1・∂uH1/∂ wH12
={(zO1-t1) wO11 + (zO2-t2) wO21} f’(uH1) x2
∂E/∂ wH21 =∂E/∂ zH2 ・∂zH2/∂ uH2・∂uH2/∂ wH21
=(∂E/∂ zO1 ・∂zO1/∂ zH2 +∂E/∂ zO2 ・∂zO2/∂ zH2)・∂zH2/∂ uH2・∂uH2/∂ wH21
={(zO1-t1) wO12 + (zO2-t2) wO22} f’(uH2) x1
∂E/∂ wH22 =∂E/∂ zH2 ・∂zH2/∂ uH2・∂uH2/∂ wH22
=(∂E/∂ zO1 ・∂zO1/∂ zH2 +∂E/∂ zO2 ・∂zO2/∂ zH2)・∂zH2/∂ uH2・∂uH2/∂ wH22
={(zO1-t1) wO12 + (zO2-t2) wO22} f’(uH2) x2
∂E/∂ wH31 =∂E/∂ zH3 ・∂zH3/∂ uH3・∂uH3/∂ wH31
=(∂E/∂ zO1 ・∂zO1/∂ zH3 +∂E/∂ zO2 ・∂zO2/∂ zH3)・∂zH3/∂ uH3・∂uH3/∂ wH31
={(zO1-t1) wO13 + (zO2-t2) wO23} f’(uH3) x1
∂E/∂ wH32 =∂E/∂ zH3 ・∂zH3/∂ uH3・∂uH3/∂ wH32
=(∂E/∂ zO1 ・∂zO1/∂ zH3 +∂E/∂ zO2 ・∂zO2/∂ zH3)・∂zH3/∂ uH3・∂uH3/∂ wH32
={(zO1-t1) wO13 + (zO2-t2) wO23} f’(uH3) x2
よくわからないという人は、もう一度前回の記事を読み直してみて下さい。
>> 【実はとても簡単だった!】誤差伝播法をシンプルにわかりやすく解説します。
Excelシートに入力する
それでは、以上の式をExcelシートに入力していきます。
先ほどAC列まで入力しましたので、AD列から次のように入力します。
横に長いので、2つの画面に分けます。
(1枚目)
(2枚目)
最初にAC列までのスナップショットを載せましたが、A~D列までを隠していました。
このようになっています。
D列で損失関数Eを計算しています。
C列ではその時のパラメータで計算した結果、○か×のどちらの判定になったかを表示しています。
B列ではC列で判定した結果と教師データを比較して、合っていればOK、間違っていたらNGと表示させています。
そして44枚の教師データを何巡も読み込んで学習を繰り返しますが、1巡するごとに44枚のうち正解が何%だったかをA列に算出しています。
学習結果
学習率0.5の場合
学習率0.5で学習させた結果、9巡目で終了しました。
求めるパラメータ(重みとバイアス)は38個ありましたが、学習後の値は次のようになりました。
このパラメータであれば、少なくとも44枚の教師データはすべて間違いなく判定できるということです。
正解率の推移は次の通りです。
学習率が大きいほど早く収束
44枚の教師データをたったの9回読み込んだだけで、100%の正解を出せるようになりました。
学習率を変えたらどうなるのでしょうか?
学習率を0.2、0.5、1で学習させた場合の結果は、次のようになりました。
学習率が大きいほど早く学習が終了しました。
ηが1の場合は、たったの6回で終了しました。
教師データ以外の画像で試してみる
ところで、この正解率100%は44枚の画像に対してです。
512通りある組み合わせのうちの44通りについて、100%の正解を出せるようになったにすぎません。
他の画像はどう認識するのでしょうか?
これは教師データには入っていませんが、いかにもありそうなパターンですね。
先ほどの学習後の行に、この値を入力してみましょう。
すると、ちゃんと✕と認識しました。
詳しく見てみると、〇の確率は37%、✕の確率は63%と計算しています。
たった6回見ただけでで44枚をすべて認識できるようになった上に、他の画像もちゃんと認識できるようになるとは、、、管理人は絶対に負けますね。
Excelにもこのような頭脳を持たせることができる。
なかなか感動的ではありませんか?