「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>ニューラルネットワーク]] *目次 [#s4413bb4] #contents *概要 [#ha063b73] 学習フェーズでは、信号は逆方向に伝播する。 -学習とは、重みパラメタを自動獲得するためのもの。 -実際のニューラルネットワークの重みパラメタは、 --数千、数万になるため、手動での設定は不可能。 --更に層を深めた深層学習(deep learning)では数億にも登る。 -重みパラメタの自動獲得のため、損失関数という指標を導入する。 --損失関数を基準に??その値が最小になるように重みパラメタを探す。 --このような値を探し出すためには、勾配法という手法を用いる。 *学習はデータ駆動 [#mbc3dc7d] -MNISTデータセットの分類処理を行うアルゴリズムを考え出すのは困難。~ しかし、機械にデータを学習させる機械学習を用いれば分類処理が実現可能。 >人間が(暗黙的な学習によって、)これらを判別することはできる。~ 従って、人間の脳も、一部は、このようなデータ駆動で動いているのかもしれない。 -このように、アルゴリズムを捻り出すのではなく、データを有効活用して解決する方法に、~ 画像から[[特徴量>#be25bbf1]]を抽出し、[[特徴量>#be25bbf1]]のパターンを機械学習の技術で学習するという方法がある。 *機械学習 [#z9e63650] **特徴量 [#be25bbf1] -入力された学習データから特徴量と呼ばれる数値を抽出する。 -学習データにどのような特徴があるかを数値化したもの。 -特徴量の抽出は人間が設計し実装する必要がある。 -抽出した特徴量を元に機械はパターン・経験則をモデルを使って学習する。 ***特徴量選択 [#l29fa353] 入力画像データから、本質的なデータを抽出できるように設計された変換器を指す。 -画像データの特徴量は通常、ベクトルを使用して表される。 -SIFT, SURF, HOGなど、人が設計した変換器によって画像データをベクトル化する。 **機械学習 [#yb9b7687] ベクトル化された画像データを機械学習のSVMやKNNなどの識別器で学習させる。 *深層学習(deep learning) [#h9af97d2] 特徴量についても機会が学習する。 **損失関数 [#l7995afd] -深層学習(deep learning)では一つの指標を手がかりに最適なパラメタを探索する。 -この指標を損失関数を呼び、任意の関数を用いることが出来る。 ***2乗和誤差 [#o54ca9e8] ニューラルネットワークの出力と正解となる教師データの各要素の差の二乗の総和の2分の一。 -式 2 E = 1/2 Σ (yk-tk) k --説明 ---k:データの次元数 ---yk:ニューラルネットワークの出力 ---tk:教師データ --例(k=10) ---yk:ニューラルネットワークの出力~ =[0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]~ [[ソフトマックス関数>ニューラルネットワーク(推論)#b77bdfd7]]の出力(全て足して1.0になる。) ---tk:教師データ~ =[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]~ ※ 正解ラベルを1、ソレ以外を0とする、one-hot表現 -Python --実装 """This is a test program.""" import numpy as np def mean_squared_error(yk, tk): """損失関数(2乗和誤差)""" return 0.5 * np.sum((yk - tk)**2) tk = np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0]) yk = np.array([0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]) print(mean_squared_error(yk, tk)) yk = np.array([0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]) print(mean_squared_error(yk, tk)) --出力~ 正解(tk)に対応する確率(yk)が高ければ高いほど、1に近いデータになる。 ---tkで2が正解の場合、ykで2の確率が一番高いとしたデータの場合のE。 0.0975 ---tkで2が正解の場合、ykで7の確率が一番高いとしたデータの場合のE。 0.5975 -前者の損失関数(2乗和誤差)の出力Eの方が''大きく''、~ 前者のykがより適合していることを示している。 ***交差エントロピー誤差 [#p5eb632c] -正解ラベルのykデータの底がeの自然対数 log eを計算する。 - y = -log xでは、x=0-1の場合、xが0に近づくほど、yは大きな値になる。 -式 E = - Σ tk log yk k --説明 ---log:logは底がeの自然対数 log e ---k:データの次元数 ---yk:ニューラルネットワークの出力 ---tk:教師データ --例(k=10) [[同上>#o54ca9e8]] -Python --実装 """This is a test program.""" import numpy as np def mean_squared_error(yk, tk): """損失関数(交差エントロピー誤差)""" delta = 1e-7 # log(0)はマイナス∞になるのを微小な値を足して防止。 return -np.sum(tk * np.log(yk + delta)) tk = np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0]) yk = np.array([0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]) print(mean_squared_error(yk, tk)) yk = np.array([0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]) print(mean_squared_error(yk, tk)) --出力~ 正解(tk)に対応する確率(yk)が低ければ低いほど、大きいデータになる。 ---tkで2が正解の場合、ykで2の確率が一番高いとしたデータの場合のE。 0.510825457099 ---tkで2が正解の場合、ykで7の確率が一番高いとしたデータの場合のE。 2.30258409299 -前者の損失関数(交差エントロピー誤差)の出力Eの方が''小さく''、~ 前者のykがより適合していることを示している。 **ミニバッチ学習 [#h15bc15d] -ミニバッチ学習では、上記の損失関数を訓練用データセットに対して適用する。 -ここでは、訓練用データセットに対する損失関数の総和を指標とする。 -式 E = -1/N ΣΣ tnk log ynk n k --説明 ---[[交差エントロピー誤差>#p5eb632c]]の式をN個のデータを含む訓練用データセット用に拡張する。 ---最後に、Nで割って正規化する(データ1個あたりの平均の損失関数を求める)。 --例([[MNISTデータセット>ニューラルネットワーク(推論)#c18ded2a]]を使用する) -Python --実装 """This is a test program.""" import numpy as np def mean_squared_error(ynk, tnk): """損失関数(交差エントロピー誤差)""" if ynk.ndim != 1: # 一次元化 tnk = tnk.reshape(1, tnk.size) print(tnk) ynk = ynk.reshape(1, ynk.size) print(ynk) batch_size = ynk.size # ynk.shape[0] print("batch_size:" + str(batch_size)) delta = 1e-7 # log(0)はマイナス∞になるのを微小な値を足して防止。 return - 1 / batch_size * (np.sum(tnk * np.log(ynk + delta))) TNK = np.array([[0, 0, 1, 0, 0, 0, 0, 0, 0, 0], \ [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]) YNK = np.array([[0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0], \ [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]]) print("mean_squared_error:" + str(mean_squared_error(YNK, TNK))) YNK = np.array([[0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0], \ [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]]) print("mean_squared_error:" + str(mean_squared_error(YNK, TNK))) --出力