9 Deep Learning 損失関数 2乗和誤差

9.1 2乗和誤差

最も有名な損失関数は2乗和誤差(mean squared error)だという。次式であらわされる。ここではテストデータを教師データと呼称する。(呼称している。)

\[ E = \frac{1}{2} \sum_k (y_k – t_k)^2 \tag{9.1.1} \]

ニューラルネットワークの推論の出力値は確率で示されることを説明した。
このyが0~9の手書き文字の推論の出力結果だとすると、0の確率は0.1、1の確率は0.05、2の確率は0.6である。一方、tは教師データで正解となるラベルのみ1とするone-hot-label表現をしているが、この場合は正解は「2」である。

実装は下記

上図における例2は正解に近い出力であり、例1は間違ったと言っていいほど正解に遠い出力である。例1に比べて、例2のほうが出力値が小さいことに注目されたい。

このように、損失関数の値を小さくすることが、ニューラルネットワークの目的であり、損失関数の値が大きいほど、性能が悪いニューラルネットワークであると言える。性能の悪さを最小にすることと、性能の良さを最大にすることは同義である。

ディープラーニングの記事

8 Deep Learning ニューラルネットワークの学習

ここで言う「学習」とは訓練データから最適な重みパラメータの値を自動で獲得することを指す。バイアスの更新は、以降解説する誤差逆伝播法で示す。
「学習」の「指標」として、損失関数を定義し、この値が最も小さくなる重みパラメータを捜し出して更新することが、「学習」の目的である。

8.1 訓練データとテストデータ

ニューラルネットワークの特徴は、データから学習する点にある。Deep Learningとは Deep Neural Networkのことであり、隠れ層である中間層を含め、3層以上のニューラルネットワークのことを指す。
層が深くなると重みW1,W2….パラメータの数が、数千、数万に及び、
深くすると数億に及ぶ(らしい)。
このデータとはどこからくるの?という疑問は残るが、ありがたい教えの写経を続ける。

訓練データとテストデータ

機械学習の問題では、訓練データとテストデータの2つに分けて、学習や実験などを行うのが一般的である。
この場合、訓練データだけを使って、学習を行い、最適なパラメータ(重み、バイアス)を探索する。
そのあと、テストデータを使って、訓練したモデルの評価を行う。
しかしひとつのデータセット(訓練データとテストデータ)だけでパラメータの学習と評価を行ってしまうと、正しい評価が行えないことがおきる。あるデータセットにはうまく対応できても、他のデータセットには対応できない、といったあるデータセットだけに過度に対応した状態を過学習(overfitting)がおきる。
機械学習においては、汎化能力に重点がおかれ、過学習を避けることが課題だそうだが、マリア様を作るプロジェクトでは過学習がおきても、問題がないどころが、そのほうかえってよいかもしれない。その人にとってのマリア様を作るのであって、汎化したマリア様など必要ないからである。
訓練データとテストデータはどこからくるの?という疑問は残るが写経を続ける。

8.2 損失関数

国民の幸福指標に近いものとして、ニューラルネットワークにおいて用いられる指標は、損失関数(loss function)と呼ばれる。
一般には、2乗和誤差や交差エントロピー誤差などが用いられる。
エントロピーはよくわからない概念だが、ある状態が元に戻れるかどうかを数値化したものと考えればよい。
新築の屋敷を元の状態とすると、散らかっているゴミ屋敷はエントロピーが大きいが、整頓された屋敷はエントロピーが小さいといえる。
気体はエントロピーが大きいが、個体はエントロピーが小さい。
こちらを参照した。
こちらの宇宙が発散するものならば、熱も発散し、全体的に宇宙が冷えるという早稲田大学の偉い人の講義も興味深い。

7 Deep Learning 画像認識のバッチ処理(束処理)

バッチとは束という意味である。
バッチファイルと呼ばれる.batファイルは命令列を記述しただけのテキストファイルであり、それを実行すると、コマンドプロンプトが起動する。

.batファイルの中身は以下のようになる。

命令A(電卓アプリを開く)
命令B(1+1を計算する)
命令C(演算結果をクリップボードにコピーする)
命令D(メモ帳アプリを開く)
命令E(メモ帳にクリップボードから貼り付ける)
命令F(メモ帳に”2.txt”という名前を付けて保存する。)
命令G(メモ帳アプリの終了)
命令H(電卓アプリの終了)

このバッチファイルを実行すると、2という内容の2.txtというテキストファイルができる。このバッチファイルの意味はないが、バッチファイルがどんなものかは分かるかと思われる。余計混乱させたかもしれない。

コンピュータのアプリケーションプログラムやOSは全て機械語でできており、0と1のみである。ハード的には電位が高いほうが1で低いほうが0である。(多分)

よく脆弱性のあるブログラムの修正などを聞いたことがあると思われるが、例えばユーザーが代入する余地のある配列t[100]など定義した危ないプログラムに、t[100]以上にFFEF DDFE A010 ….. AAAA などの数値を代入すると、プログラムは機械語と認識して、”予期せぬ動作”を起こすことができる。バッファオーバーフローによる、ハッキングはこのようにして行われる。機械語はアセンブリ言語というとてつもなくめんどくさい低級(知的レベルが低いという意味ではない)言語に変換ができるので、この種のハッキングを使用する場合ネットワークの知識とアセンブリ言語の知識が必要になるだろう。(そんなことをしなくても、ハッカーはエロサイトにトロイを仕込んだり、”友達”の家にいくほうが速いというだろう。)

話がずれたが、以下写経する。

ニューラルネットワークの各層の重みを出力する。

行列の内積は次元の要素数が一致している必要があるが、下図のように一致が確認できる。

上記は画像データ1枚を入力した時の、推論処理の流れである。バイアスは省略している。画像を複数枚同時に処理したいときは、以下のようになる。xの形状を100×784とすると、下図のようになる。

画像がお札の束のようになっているイメージである。(というわかりやすい教えが本に書かれている。)

数値計算を行うライブラリ(関数群)には、大きな配列の計算を効率よく行う(演算時間を短縮する)最適化が行われている。データ転送がボトルネックになる場合は、バッチ処理を行うことによって、データの読み込みに対して、演算の割合を多くすることができる。つまり、小さい配列をなんども読み込んで計算するより、大きい配列を一度に計算したほうが速いということである。

バッチ処理による画像認識予想プログラムの実装は下図のようになる。

range()関数はrange(start,end)のように指定すると、startから end-1までの整数のリストを作る。
range(start,end,step)のように指定すると、stepで指定された値だけ増加するリストを作る。
具体例は下記

リスト関数list()についてはこちらを参照

x[i:i+batch_size]という奇妙な表記は、x[i]からx[i+batch_size]まで取り出すということである。

この例では、batch_size = 100なので x[0:100], x[100:200],….のように先頭から100枚ずつの束処理を行う。

argmax()関数は最大値を出力する関数ではない。最大値のインデックスを返す関数である。つまり、x=array([1,3,5,2])であれば、argmax(x) の出力は2である。(0から数えるため)

argmax関数のaxisという難解な引数については、配列の何次元めを指定するかということであるそうである。(axisの日本語訳は”軸”である)

詳細は下記。


axis = 1 を指定すると 1次元目、[0.1,0.8,0.1],[0.3,0.1,0.6]…の内、最大値のインデックスが1 2 1 0を指すことがわかる。

比較演算子の使い方については下図を参照されたい。

次回はニューラルネットワークの学習について記述する。

6 Deep Learning ニューラルネットワークの推論処理

前回のMNISTデータセットに対して、以前実装したニューラルネットワークを利用して、入力画像の数字を推論する処理をPythonで実装する。

ここで、入力層を784個、出力層を10個のニューロンで構成する。
入力層の784という数字は、画像サイズの28*28=784から、また、出力層の10という数字は、10クラス分類(数字の0から9の10クラス)から来ている。
また、隠れ層が2つあり、一つ目の隠れ層が50個のニューロン、二つ目の隠れ層が100個のニューロンを持つものとする。
この、50と100という数字は任意の値(“適当な”値)にすることができる。
実装は下図のようになる。


Accuracy:0.9352という出力は 93.52%正しく分類することができた。ということを表す。
predict()関数によって、ニューラルネットワークの推論を行い、その出力y(一次元配列)の内、最大の値p(=np.argmax(y))とt[i](i=0,1,2,…,9999)が一致すれば
accuracy_cntを1加算する。一致しなければ、何もしない。
それをlen(x)(=10000)回反復して、Accuracy(認識精度)を求めて表示する。
Accuracyの求め方はaccuracy_cnt/ 10000(反復回数)である。
floatでキャストすることによって浮動小数点の計算にしていることに注意されたい。


xやt、そもそもpklとはどこからやってきたのか?という疑問は当然生じる。

これが”訓練データ”や”テストデータ”とよばれるものであり、”ビッグデータ”と呼ばれるものである。
これをどのように取得するのかが問題になってくる。

またsoftmax()関数はいらないと言っておきながら、使用している理由は今後説明される(はずである)。

5 Deep Learning 手書き数字認識 MNIST

MNIST データセット

MNISTデータセットは機械学習の分野で有名なデータセットである。
MINISTの画像は28×28のグレー画像で、各ピクセルは0~255の値をとる。それぞれの画像データに対しては、0~9の対応するラベルが与えられている。
load_mnist関数の引数 flattenフラグは 配列を1次元配列にするか否か、 normalizeは入力画像を0.0~1.0の値に正規化するかどうかを設定する。
normalizeをFalseにすれば、入力画像のピクセルは0~255になる。3つ目の引数のone_hot_labelはラベルをone_hot表現として格納するかどうかを設定する。
one-hot表現とは[0,0,1,0,0,0,0,0,0,0]のように、正解となるインデックスの配列の内容だけが1で、それ以外は0の配列である。
実装を下図のようになり、


出力は下図のようになる。