ニューラルネットワーク(学習)
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfras...
-[[戻る>深層学習(deep learning)]]
--[[パーセプトロン]]
--[[ニューラルネットワーク]]
---[[ニューラルネットワーク(推論)]]
---ニューラルネットワーク(学習)~
・[[深層学習の誤差逆伝播法]]~
・[[深層学習のテクニック]]
*目次 [#s4413bb4]
#contents
*学習の概要 [#ha063b73]
[[ニューラルネットワーク]]においては、[[特徴量>#be25bbf1]...
**[[機械学習>機械学習(machine learning)#t209d0ea]]の場...
***[[特徴量>機械学習(machine learning)#t209d0ea]]の選択...
-構造化データ~
--特徴量を表から選択する。
--場合によっては次元圧縮したりする。
-非構造化データ~
--画像~
入力画像データから、本質的なデータを抽出できるように設計...
---画像データの特徴量は通常、ベクトルを使用して表される。
---SIFT, SURF, HOGなど、人が設計した変換器によって画像デ...
***[[特徴量>機械学習(machine learning)#t209d0ea]]の学習...
-構造化データ~
機械学習の[[様々なアルゴリズム>データマイニング(DM)- CR...
-非構造化データ~
--画像~
ベクトル化された画像データを機械学習の~
[[SVMやKNNなどの識別器>機械学習(machine learning)#mcb6a...
**[[深層学習>深層学習(deep learning)]]の場合 [#k2f63d97]
***重みの自動獲得 [#f8216a8e]
学習フェーズでは、信号は逆方向に伝播する。
-学習とは、重みパラメタを自動獲得するためのもの。
-実際のニューラルネットワークの重みパラメタは、
--数千、数万になるため、手動での設定は不可能。
--更に層を深めた深層学習(deep learning)では数億にも登る。
-重みパラメタの自動獲得のため、
--[[損失関数>#l7995afd]]という指標を導入する。~
[[損失関数>#l7995afd]]を使用して値が最小(最大)になるよ...
--このようなパラメタを探し出すためには、[[勾配法>#v7a3cd9...
[[勾配>#e083729e]]は、各場所で[[(損失)関数>#l7995afd]]...
***学習はデータ駆動 [#mbc3dc7d]
-MNISTデータセットの様な画像の分類処理を行うアルゴリズム...
しかし、機械にデータを学習させる機械学習を用いれば分類処...
>人間が(暗黙的な学習によって、)これらを判別することはで...
従って、人間の脳も、一部は、このようなデータ駆動で動いて...
-このように、アルゴリズムを捻り出すのではなく、データを有...
画像から[[特徴量>#be25bbf1]]を抽出し、[[特徴量>#be25bbf1]...
**損失関数(誤差関数) [#l7995afd]
-損失関数は、誤差関数とほぼ同じか、より包括的な概念。
--予想データと正解データの出力の間に、~
どのくらい誤差があるのかを評価する関数。
--作成した予測モデルの精度を評価する際に使われ、
--値(誤差)が小さければ小さいほど正確なモデルと言える。
---モデル関数とデータ群の誤差という文脈では誤差関数と呼ば...
---学習の文脈では損失関数と呼ばれ、誤差関数以外にも例えば...
-[[深層学習>深層学習(deep learning)]]では一つの指標を手...
-この指標を損失関数を呼び、パラメタに対して連続的に変化す...
-これは学習時に、[[微分>DS:数学的基礎 - 微分・偏微分]]に...
***損失関数上の地形 [#tc9c2080]
-ほとんどの最適化アルゴリズムは、正確な勾配やヘッセ行列を...
--勾配の悪条件
---鞍点~
・ある方向から見ると極小値であるが、別の方向から見ると極...
・鞍点の数はパラメタの数に対して指数関数的に増加するので...
---平地:ほぼ水平な領域~
・勾配が0となるような平地領域ではSGDで学習が進まなくなる。~
・MomentumSGDなどの慣性を用いた最適化アルゴリズムで解決を...
---崖:ほぼ垂直な領域~
・勾配が急すぎて(勾配爆発を起こし)、パラメタが遠くに吹...
・同じ値の掛け算が繰り返し行われる場合に発生~
・RNNなどで多く現れ、長期依存性が現れるのもこの地形が原因。~
・勾配の大きさに上限を設ける勾配クリッピングが有効。
---ノイズやバイアス~
・ノイズやバイアスが加わった場合、勾配が滑らかにならずギ...
・これを回避するためには、損失関数をより平坦な代理損失関数...
--ヘッセ行列の悪条件
---ヘッセ行列~
関数の二階偏導関数全体が作る正方行列で対称行列~
・固有値の符号をみることにより極小点や凸性の判定を行える。~
・固有値が全て正であれば、凸関数になるので大域解が求まる...
---悪条件~
ヘッセ行列の特異値が非常に大きいまたは非常に小さい場合、...
・極端な比率の変数:ある変数が他の変数に比べて数桁大きい...
・局所的な不連続性:関数が局所的な不連続性や非線形性を持...
-[[見せかけの最適化を防ぐアルゴリズム>#nec068c7]]
--SGD (MomentumSGD, NAG)
--AdaGrad
--Rmsprop
--AdaDelta
--Adam
-勾配降下のプログラム実装
--重み更新は勾配の引き算:Θ = Θ - 勾配
--ミニバッチでは損失をΣしたものをサイズで割って平均を取る。
--この値に学習率(0.01などの値)を掛ける。
--[[個別のアルゴリズムの実装は数式より想像できる。>#nec06...
***2乗和誤差 [#o54ca9e8]
回帰の場合(ニューラルネットワークの出力と正解となる教師...
-式
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]~
[[Softmax関数>ニューラルネットワーク(推論)#b77bdfd7]]の...
---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])
# 推定データ1の誤差
yk = np.array([0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1,...
print(mean_squared_error(yk, tk))
# 推定データ2の誤差
yk = np.array([0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6,...
print(mean_squared_error(yk, tk))
--出力~
正解(tk)に対応する確率(yk)が
---高ければ高いほど、0に近いデータになる。~
tkで2が正解の場合、ykで2の確率が一番高いとしたデータの...
0.0975
---低ければ低いほど、1に近いデータになる。~
tkで2が正解の場合、ykで7の確率が一番高いとしたデータの...
0.5975
-前者の損失関数(2乗和誤差)の出力が小さい前者のykがより適...
***多クラス交差エントロピー誤差 [#p5eb632c]
多値分類(正解ラベルのykデータの底がeの自然対数 log eを計...
-式
--通常版
E = - Σ tk log yk
k
--ミニバッチ対応版
1
E = - ─ Σ Σ tnk log ynk
N n k
--説明
---log:logは底がeの自然対数 log e
---k:データの次元数
---yk:ニューラルネットワークの出力
---tk:教師データ
--例(k=10)~
[[同上>#o54ca9e8]]
-Python
--実装
"""This is a test program."""
import numpy as np
def cross_entropy_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,...
print(cross_entropy_error(yk, tk))
yk = np.array([0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6,...
print(cross_entropy_error(yk, tk))
--出力~
正解(tk)に対応する確率(yk)が
---高ければ高いほど、0に近いデータになる。~
tkで2が正解の場合、ykで2の確率が一番高いとしたデータの...
0.510825457099
---低ければ低いほど、大きいデータになる。~
tkで2が正解の場合、ykで7の確率が一番高いとしたデータの...
2.30258409299
--ミニバッチ対応版~
上記を平均にしている。
return - np.sum(tk * np.log(yk + delta)) / yk.shape[0]
-前者の損失関数(交差エントロピー誤差)の出力が小さい前者の...
***二値交差エントロピー誤差 [#uf4f7d8f]
ミニバッチ対応版
return np.mean(- y * np.log(p) - (1-y) * np.log(1-p))
**勾配の計算 [#e083729e]
[[微分(偏微分)>DS:数学的基礎 - 微分・偏微分]]で求めた...
各場所で関数の値を最も減らす方向(である可能性が高い)。
***勾配降下法 [#v7a3cd9d]
-勾配法では、広大なパラメタ空間から、複雑な[[損失関数>#l7...
最小(最大)値を出力する鞍点(saddle point)を、勾配を使...
--勾配降下法 : (誤差などが)最小になるパラメタ値を探す。
--勾配上昇法 : (確率などが)最大になるパラメタ値を探す。
-ランダムにデータを選択する場合
--1つのデータを選択する場合、[[確率的勾配降下法(SGD)>...
--n個のデータを選択し、損失の平均値を使用する場合、ミニ...
--全てのデータを選択し、損失の平均値を使用する場合、バッ...
-注意点
--勾配の指す方向に最小(最大)値があることは保証されない。
--複雑な関数の場合は、勾配の指す方向に最小(最大)値が無...
-ポイント~
学習を如何に
--効率良く進めるか。
--上手く最適解に収束させるか。
---局所最適解 ✕
---大域最適解 ○
--上手く鞍点を脱するか。
***曲線の勾配計算 [#k80130c4]
-式
df(x0, x1) df(x0, x1)
───── , ─────
dx0 dx1
--説明
---すべての変数の[[偏微分>DS:数学的基礎 - 微分・偏微分]]...
---[[上記の例>#z8297246]]なら、x0=3, x1=4の場合、勾配は、...
-Python
--実装
"""This is a test program."""
import numpy as np
def numerical_gradient(f, x01):
"""偏微分"""
h = 1e-4 # 微小な値hとして1の-4乗を用いる
grad = np.zeros_like(x01) # x01と同じ形状で要素が0。
for idx in range(x01.size):
tmp_val = x01[idx]
# 前方差分から中心差分にして誤差減
# f(x + h)
fxh1 = f(tmp_val + h)
# f(x - h)
fxh2 = f(tmp_val - h)
# (f(x + h) - f(x - h)) / 2 * h
grad[idx] = (fxh1 - fxh2) / (2 * h)
return grad
def function_2(x):
return np.sum(x**2)
print(numerical_gradient(function_2, np.array([3.0, 4.0]...
print(numerical_gradient(function_2, np.array([0.0, 2.0]...
print(numerical_gradient(function_2, np.array([3.0, 0.0]...
--出力
[ 6. 8.]
[ 0. 4.]
[ 6. 0.]
--参考~
https://github.com/oreilly-japan/deep-learning-from-scrat...
---x = -2.0 - 2.5, y = -2.0 - 2.5 の範囲の0.25刻みのメッ...
---メッシュグリッドはm行n列の配列なので、これをflatten()...
---np.array([X, Y])で x0, x1 の 2 行 m * n 列の配列にする。
---バッチ関数ではforで 1 行つづ取り出し、m * n 列のベクト...
---各場所(x0, x1)での、勾配をplt.quiver使用してベクトル...
***曲面の勾配計算 [#t9bd79ba]
-式
df(x0, x1)
x0 = x0 - η ─────
dx0
df(x0, x1)
x1 = x1 - η ─────
dx1
--説明
---上記は、一回の更新式で、勾配法では、このステップを繰り...
---ηは学習率で、一回の学習でどれだけ学習すべきか?=どれ...
---学習率は、0.01、0.001など前もって値を決める、~
それから正しく学習できているか確認しながら調整する。
-Python~
以下の式の最小値を勾配法で求める。
2 2
f(x0, x1) = x0 + x1
--実装
import numpy as np
def numerical_gradient(f, x01):
"""偏微分"""
h = 1e-4 # 微小な値hとして1の-4乗を用いる
grad = np.zeros_like(x01) # x01と同じ形状で要素が0。
# print("x01:" + str(x01));
for idx in range(x01.size):
tmp_val = x01[idx]
# 前方差分から中心差分にして誤差減
# f(x + h)
fxh1 = f(tmp_val + h)
# f(x - h)
fxh2 = f(tmp_val - h)
# (f(x + h) - f(x - h)) / 2 * h
grad[idx] = (fxh1 - fxh2) / (2 * h)
return grad
def gradient_descent(f, init_x01, lr, step_num):
print("ln : step_num = " + str(lr) + " : " + str(ste...
x01 = init_x01
for i in range(step_num):
grad = numerical_gradient(f, x01)
x01 -= lr * grad
return x01
def function_2(x):
return np.sum(x**2)
init_x = np.array([-3.0, 4.0])
print(gradient_descent(function_2, init_x, 0.1, 100))
# 学習率が大きすぎる。
init_x = np.array([-3.0, 4.0])
print(gradient_descent(function_2, init_x, 10.0, 100))
# 学習率が小さすぎる。
init_x = np.array([-3.0, 4.0])
print(gradient_descent(function_2, init_x, 1e-10, 100))
--出力
ln : step_num = 0.1 : 100
[ -6.11110793e-10 8.14814391e-10]
ln : step_num = 10.0 : 100
[ -1.91613251e+13 -1.26893162e+12]
ln : step_num = 1e-10 : 100
[-2.99999994 3.99999992]
***NNに対する勾配 [#p1598e1c]
ニューラルネットワークの学習における勾配は、~
重みパラメタに関する[[損失関数>#l7995afd]]の勾配となる。
-式
┌ w11 w21 vw31 ┐
W = │ │
└ w12 w22 vw32 ┘
┌ dL dL dL ┐
│ ── ── ── │
dL │ dw11 dw21 dw31 │
── =│ │
dW │ dL dL dL │
│ ── ── ── │
└ dw12 dw22 dw32 ┘
-Python~
--gradient_simplenet.py~
https://github.com/oreilly-japan/deep-learning-from-scrat...
---重みパラメタをインスタンス変数に持つ。~
2 行 3 列の行列で、標準正規分布関数に従う乱数を生成
---x = 入力データ, t = 正解ラベル
---predict(x)メソッド : [[dot product(ドット積)>NumPy#l...
---loss(x, t)メソッド : [[損失関数>#l7995afd]](の値を求...
predict ---> softmax ---> cross_entropy_error
>
+predict(推論する)
+softmax([[Softmax関数>ニューラルネットワーク(推論)#b77...
+cross_entropy_error([[交差エントロピー誤差>#p5eb632c]])
---nditerで多次元配列に対応した勾配の計算メソッド : commo...
https://github.com/oreilly-japan/deep-learning-from-scrat...
--実行~
フォルダ構成を維持した状態でch04に定義した以下のファイル...
C:\deep-learning-from-scratch-master\ch04>python Untitle...
--simpleNetを使って推論/学習
---実装
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルを...
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradient
from gradient_simplenet import simpleNet
print("=================================================...
print("=================================================...
net = simpleNet()
print("W:" + str(net.W))
x = np.array([0.6, 0.9])
p = net.predict(x)
print("p:" + str(p))
t = np.array([0, 0, 1])
l = net.loss(x, t)
print("loss:" + str(l))
---出力~
W:[[ 1.92087598 0.63971089 -0.26820797]
[ 0.58411529 -0.04610929 -0.88999594]]
p:[ 1.67822935 0.34232817 -0.96192113]
loss:2.92853604814
--simpleNetを使って勾配を求める
---実装
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルを...
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradient
from gradient_simplenet import simpleNet
print("=================================================...
print("=================================================...
net = simpleNet()
print("W:" + str(net.W))
x = np.array([0.6, 0.9])
t = np.array([0, 0, 1])
f = lambda w: net.loss(x, t)
dW = numerical_gradient(f, net.W)
print("dW:" + str(dW))
---出力~
==================================================
==================================================
W:[[ 1.83160192 0.4900981 -0.94188042]
[-0.24946104 2.91410946 -0.00695892]]
dW:[[ 0.06708443 0.51711391 -0.58419835]
[ 0.10062665 0.77567087 -0.87629752]]
-Wは、
W : [[ w11 = 1.83160192 w21 = 0.4900981 w31 = -0.9...
[ w12 = -0.24946104 w22 = 2.91410946 w32 = -0.0...
dL/dW : [[ dL/dw11 = 0.06708443 dL/dw21 = 0.51711391 dL/...
[ dL/dw12 = 0.10062665 dL/dw22 = 0.77567087 dL/...
--w11を h 増やすと、0.06708443 h 増加する。
--w12を h 増やすと、0.10062665 h 増加する。
--w21を h 増やすと、0.51711391 h 増加する。
--w22を h 増やすと、0.77567087 h 増加する。
--w31を h 増やすと、-0.58419835 h 増加する( = 減少する)。
--w32を h 増やすと、-0.87629752 h 増加する( = 減少する)。
--勾配がプラスならhをマイナス方向に、マイナスならプラス方...
***見せかけの最適化を防ぐ [#nec068c7]
-停留点は、極大点、極小点、鞍点のいずれかになりうる。
--鞍点は、ある次元では最小だが、別の次元では最大(最小で...
--最小化問題において、極小点は局所最小点または大域的最小...
--(最大化問題において、極大点は局所最大点または大域的最...
-学習率を大きく設定し、適切なタイミングで値を小さくしてい...
[[SGD (MomentumSGD, NAG)、AdaGrad、Rmsprop、AdaDelta、Ada...
**ミニバッチ学習 [#h15bc15d]
-平均を取って誤差逆伝播する。
-ミニバッチがランダムにサンプリングされている限り、~
ミニバッチから平均として算出された損失の勾配が真の勾配に...
***バッチ、ミニバッチ、オンライン学習 [#g72434c9]
-バッチ学習(一括学習)
--全てのサンプルを一度に用いて[[勾配>#e083729e]]を求める...
--機械学習のアルゴリズムでは基本的にバッチ学習が採用され...
--ただし、深層学習では、データが多過ぎるため、現実的でな...
-オンライン学習(逐次学習)
--ひとつのサンプルのみを用いて[[勾配>#e083729e]]を求める...
--ノイズや外れ値の影響を受け易く、解が適切な値に収束し難...
-ミニバッチ学習~
データを幾つかの塊に小分けにして、その塊毎に[[勾配>#e0837...
--[[勾配>#e083729e]]計算に損失関数の平均値を使用しても問...
--バッチ学習とオンライン学習の折衷案で、多くの場合におい...
---バッチ学習ほど学習時間がかからず、
---オンライン学習ほど解の収束が不安定にならない。
||バッチ学習(一括学習)|ミニバッチ学習|オンライン学習(...
|効率|✕|○|◎|
|安定性|◎|○|✕|
***ミニバッチ学習を訓練用データセットに適用 [#k8f7bcb2]
-ミニバッチ学習では、上記の損失関数を訓練用データセットに...
-ここでは、訓練用データセットに対する損失関数の総和を指標...
-式
E = -1/N ΣΣ tnk log ynk
n k
--説明
---[[交差エントロピー誤差>#p5eb632c]]の式をN個のデータを...
---最後に、Nで割って正規化する(データ1個あたりの平均の...
--例([[MNISTデータセット>ニューラルネットワーク(推論)#...
-Python
--実装
---one-hot表現の場合
"""This is a test program."""
import numpy as np
def mean_squared_error(ynk, tnk):
"""損失関数(交差エントロピー誤差)"""
print("tnk:" + str(tnk))
print("ynk:" + str(ynk))
batch_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 +...
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....
[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...
YNK = np.array([[0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 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...
---one-hot表現でない場合
"""This is a test program."""
import numpy as np
def mean_squared_error(ynk, tnk):
"""損失関数(交差エントロピー誤差)"""
print("tnk:" + str(tnk))
print("ynk:" + str(ynk))
batch_size = ynk.shape[0]
print("batch_size:" + str(batch_size))
delta = 1e-7 # log(0)はマイナス∞になるのを微小な値を...
ynk = ynk + delta
print("arange:" + str(ynk[np.arange(batch_size), tnk...
return - 1 / batch_size * (np.sum(np.log(ynk[np.aran...
TNK = np.array([2, 2])
YNK = np.array([[0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 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...
YNK = np.array([[0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 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...
--出力~
[[同上>#p5eb632c]]
***バッチサイズ、イテレーション数、エポック数 [#t183c375]
-バッチサイズ
--ミニバッチ[[勾配降下法>#v7a3cd9d]]のサブセットのサイズ
--訓練データサイズをバッチサイズで割った値
--1,000件の訓練データでバッチサイズを200にすると、~
サブセットのサイズは200件でバッチの回数は5回になる。
-イテレーション数
--前述の訓練データ中のバッチ回数がイテレーション数
--訓練データサイズとバッチサイズが決まれば自動的に決まる。
-エポック数
--一つの訓練データを何回繰り返して学習させるか?
--深層学習ではパラメタが収束するまで同じ訓練データで繰り...
--学習回数(エポック数)を一定以上増加させると、過学習が...
-参考~
機械学習/ディープラーニングにおける~
バッチサイズ、イテレーション数、エポック数の決め方 - Qiita~
https://qiita.com/kenta1984/items/bad75a37d552510e4682
***適切なバッチサイズの選択 [#a85f1623]
-適切なバッチサイズを選ぶ事が、学習を上手く行うために必要...
--大きくした場合
---大まかな特徴を捉えるため精度は下がる。
---パラメタの更新が少ないため計算コストは下がる。
--小さくした場合
---精度は上がる。小さすぎると学習が終了しない可能性がある。
---1件毎に誤差逆伝播処理するため計算回数=コストは上がる。
--その他注意点
---GPU を用いて計算する際は、2 のべき乗にバッチサイズを設...
---バイアスがかからないようにミニバッチはランダムに選ぶ。
-CNNでの学習例~
[[バッチサイズ500のままエポック数を増やせば>#t183c375]]よ...
--バッチサイズ5
---そもそも学習が上手くできていない。
---1つ1つのデータに敏感に反応し過ぎて学習が難しい。
--バッチサイズ50
---初めは順調に学習が進む。
---途中から過学習を起こす。
--バッチサイズ500
---過学習を起こすことなく順調に学習が進むが、
---パラメタ更新回数が少ないため、学習は途中
>※loss(損失)とacc(正解率)の進捗を確認する。
**その他 [#d6a259c8]
***[[深層学習の誤差逆伝播法]] [#c4daa80e]
***[[深層学習のテクニック]] [#j9845af7]
*実装 [#i08ec171]
**手順 [#o2a66edf]
***前提 [#a0ba9a39]
-ニューラルネットワークには適応可能な重みとバイアスがある。
-学習により、この重みとバイアスを訓練データに適応するよう...
-ニューラルネットワークの学習は、以下の4つのステップで行...
***ステップ 1 [#u61466c2]
-訓練データから、ランダムにデータを選択する。
-ここでは、損失関数の値を減らすことを目的とする。
***ステップ 2 [#lf9098f7]
-ミニバッチの損失関数を減らすために、各重みパラメタの[[勾...
-[[勾配>#e083729e]]は、損失関数の値を最も減らす方向を示す。
***ステップ 3 [#k7dba9a3]
重みパラメタを[[勾配>#e083729e]]の方向に微小量だけ更新す...
***ステップ 4 [#b640b624]
[[ステップ 1>#u61466c2]], [[ステップ 2>#lf9098f7]], [[ス...
**2層NNのクラス [#p0fb2d58]
TwoLayerNetクラス~
https://github.com/oreilly-japan/deep-learning-from-scrat...
***変数 [#ybae532d]
|#|>|変数|説明|h
|1|>|params|ニューラルネットワークの重みパラメタのディク...
|1-1||params['W1']|第1層の重み|
|1-2||params['b1']|第1層のバイアス|
|1-3||params['W2']|第2層の重み|
|1-4||params['b2']|第2層のバイアス|
|2|>|grads|numerical_gradientで計算された勾配を保持するデ...
|1-1||params['W1']|第1層の重みの勾配|
|1-2||params['b1']|第1層のバイアスの勾配|
|1-3||params['W2']|第2層の重みの勾配|
|1-4||params['b2']|第2層のバイアスの勾配|
***メソッド [#p6711ebd]
|#|メソッド シグネチャ|引数|説明|h
|1|>|__init__(self, input_size, hidden_size, output_size,...
|1-1||self|インスタンス|
|1-2||input_size|入力層のニューロンの数|
|1-3||hidden_size|隠れニューロンの数|
|1-4||output_size|出力層のニューロンの数|
|1-5||weight_init_std|・・・|
|2|>|predict(self, x):|推論を行う|
|2-1||self|インスタンス|
|2-2||x|画像データ|
|3|>|loss(self, x, t):|損失関数の値を求める|
|3-1||self|インスタンス|
|3-2||x|画像データ|
|3-3||t|正解ラベル|
|4|>|accuracy(self, x, t):|推論の精度を求める|
|4-1||self|インスタンス|
|4-2||x|画像データ|
|4-3||t|正解ラベル|
|5|>|numerical_gradient(self, x, t):|lossを使用し各重みパ...
|5-1||self|インスタンス|
|5-2||x|画像データ|
|5-3||t|正解ラベル|
|6|>|gradient(self, x, t):|numerical_gradientの高速版|
|6-1||self|インスタンス|
|6-2||x|画像データ|
|6-3||t|正解ラベル|
***学習過程の実装 [#x4872920]
[[勾配法>#v7a3cd9d]]により[[(損失)関数>#l7995afd]]を少...
-式~
[[コチラ>ニューラルネットワーク(推論)#laa37ea3]]と、[[...
--第1層 (100個のバッチ)
---x(1) =
(100, 784 = 28 * 28 pixel)
--重みパラメタ
---W(1) =
(784, x = 100)
---b(1) =
(1, x = 100)
--隠れ層 (x = 100)
---A(1) =
(100, x = 100)
---= x(2) =
(100, x = 100)
--重みパラメタ
---W(2) =
(x = 100, 10)
---b(2) =
(1, 10)
--第2層
---A(2) =
(100, 10) # 0-9の数字
-Python~
https://github.com/oreilly-japan/deep-learning-from-scrat...
--実装~
C:\deep-learning-from-scratch-master\ch04\train_neuralne...
~
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルを...
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normal...
network = TwoLayerNet(input_size=784, hidden_size=50, ou...
iters_num = 10000 # 繰り返しの回数を適宜設定する
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1
train_loss_list = []
for i in range(iters_num):
print(str(i) + " / " + str(iters_num))
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
# 勾配の計算
#grad = network.numerical_gradient(x_batch, t_batch)
grad = network.gradient(x_batch, t_batch)
# パラメータの更新
for key in ('W1', 'b1', 'W2', 'b2'):
network.params[key] -= learning_rate * grad[key]
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
plt.xlabel("Iteration")
plt.ylabel("loss")
plt.plot(range(iters_num), train_loss_list)
plt.show()
--実行~
フォルダ構成を維持した状態でch04に定義した上記ファイルを...
C:\deep-learning-from-scratch-master\ch04>python train_n...
--出力~
---CMD
0 / 10000
...
9999 / 10000
---グラフ
#ref(learning.png,left,nowrap,学習結果,60%)
***学習結果を確認する実装 [#ve66f150]
学習結果を使用して、学習データとテストデータを推論する。
-Python~
https://github.com/oreilly-japan/deep-learning-from-scrat...
--実装~
C:\deep-learning-from-scratch-master\ch04\train_neuralne...
--実行~
フォルダ構成を維持した状態でch04に定義した上記ファイルを...
C:\deep-learning-from-scratch-master\ch04>python train_n...
--出力~
1バッチ・サイクル毎に学習した重みパラメタを使用した推論結...
---CMD
train acc, test acc | 0.102183333333, 0.101
train acc, test acc | 0.783416666667, 0.7894
train acc, test acc | 0.874916666667, 0.8791
train acc, test acc | 0.8964, 0.8991
train acc, test acc | 0.907433333333, 0.9092
train acc, test acc | 0.913616666667, 0.9147
train acc, test acc | 0.9184, 0.9185
train acc, test acc | 0.923366666667, 0.9238
train acc, test acc | 0.926316666667, 0.9275
train acc, test acc | 0.9294, 0.9298
train acc, test acc | 0.932666666667, 0.9318
train acc, test acc | 0.9341, 0.9341
train acc, test acc | 0.936816666667, 0.9367
train acc, test acc | 0.940133333333, 0.9382
train acc, test acc | 0.94175, 0.9397
train acc, test acc | 0.943566666667, 0.9417
train acc, test acc | 0.945233333333, 0.9435
---グラフ
#ref(accuracy.png,left,nowrap,学習後の推論結果,60%)
***ハイパーパラメタ [#y43c81d1]
-人間が手動で設定するパラメタ
--[[確率的勾配降下法(SGD)>深層学習のテクニック#o2fe1f26...
iters_num = 10000
--1回のミニバッチのサイズ
batch_size = 100
--学習率
learning_rate = 0.1
-NNの構造に組み込まれているハイパーパラメタ
--層のサイズ
--層の深さ
終了行:
「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfras...
-[[戻る>深層学習(deep learning)]]
--[[パーセプトロン]]
--[[ニューラルネットワーク]]
---[[ニューラルネットワーク(推論)]]
---ニューラルネットワーク(学習)~
・[[深層学習の誤差逆伝播法]]~
・[[深層学習のテクニック]]
*目次 [#s4413bb4]
#contents
*学習の概要 [#ha063b73]
[[ニューラルネットワーク]]においては、[[特徴量>#be25bbf1]...
**[[機械学習>機械学習(machine learning)#t209d0ea]]の場...
***[[特徴量>機械学習(machine learning)#t209d0ea]]の選択...
-構造化データ~
--特徴量を表から選択する。
--場合によっては次元圧縮したりする。
-非構造化データ~
--画像~
入力画像データから、本質的なデータを抽出できるように設計...
---画像データの特徴量は通常、ベクトルを使用して表される。
---SIFT, SURF, HOGなど、人が設計した変換器によって画像デ...
***[[特徴量>機械学習(machine learning)#t209d0ea]]の学習...
-構造化データ~
機械学習の[[様々なアルゴリズム>データマイニング(DM)- CR...
-非構造化データ~
--画像~
ベクトル化された画像データを機械学習の~
[[SVMやKNNなどの識別器>機械学習(machine learning)#mcb6a...
**[[深層学習>深層学習(deep learning)]]の場合 [#k2f63d97]
***重みの自動獲得 [#f8216a8e]
学習フェーズでは、信号は逆方向に伝播する。
-学習とは、重みパラメタを自動獲得するためのもの。
-実際のニューラルネットワークの重みパラメタは、
--数千、数万になるため、手動での設定は不可能。
--更に層を深めた深層学習(deep learning)では数億にも登る。
-重みパラメタの自動獲得のため、
--[[損失関数>#l7995afd]]という指標を導入する。~
[[損失関数>#l7995afd]]を使用して値が最小(最大)になるよ...
--このようなパラメタを探し出すためには、[[勾配法>#v7a3cd9...
[[勾配>#e083729e]]は、各場所で[[(損失)関数>#l7995afd]]...
***学習はデータ駆動 [#mbc3dc7d]
-MNISTデータセットの様な画像の分類処理を行うアルゴリズム...
しかし、機械にデータを学習させる機械学習を用いれば分類処...
>人間が(暗黙的な学習によって、)これらを判別することはで...
従って、人間の脳も、一部は、このようなデータ駆動で動いて...
-このように、アルゴリズムを捻り出すのではなく、データを有...
画像から[[特徴量>#be25bbf1]]を抽出し、[[特徴量>#be25bbf1]...
**損失関数(誤差関数) [#l7995afd]
-損失関数は、誤差関数とほぼ同じか、より包括的な概念。
--予想データと正解データの出力の間に、~
どのくらい誤差があるのかを評価する関数。
--作成した予測モデルの精度を評価する際に使われ、
--値(誤差)が小さければ小さいほど正確なモデルと言える。
---モデル関数とデータ群の誤差という文脈では誤差関数と呼ば...
---学習の文脈では損失関数と呼ばれ、誤差関数以外にも例えば...
-[[深層学習>深層学習(deep learning)]]では一つの指標を手...
-この指標を損失関数を呼び、パラメタに対して連続的に変化す...
-これは学習時に、[[微分>DS:数学的基礎 - 微分・偏微分]]に...
***損失関数上の地形 [#tc9c2080]
-ほとんどの最適化アルゴリズムは、正確な勾配やヘッセ行列を...
--勾配の悪条件
---鞍点~
・ある方向から見ると極小値であるが、別の方向から見ると極...
・鞍点の数はパラメタの数に対して指数関数的に増加するので...
---平地:ほぼ水平な領域~
・勾配が0となるような平地領域ではSGDで学習が進まなくなる。~
・MomentumSGDなどの慣性を用いた最適化アルゴリズムで解決を...
---崖:ほぼ垂直な領域~
・勾配が急すぎて(勾配爆発を起こし)、パラメタが遠くに吹...
・同じ値の掛け算が繰り返し行われる場合に発生~
・RNNなどで多く現れ、長期依存性が現れるのもこの地形が原因。~
・勾配の大きさに上限を設ける勾配クリッピングが有効。
---ノイズやバイアス~
・ノイズやバイアスが加わった場合、勾配が滑らかにならずギ...
・これを回避するためには、損失関数をより平坦な代理損失関数...
--ヘッセ行列の悪条件
---ヘッセ行列~
関数の二階偏導関数全体が作る正方行列で対称行列~
・固有値の符号をみることにより極小点や凸性の判定を行える。~
・固有値が全て正であれば、凸関数になるので大域解が求まる...
---悪条件~
ヘッセ行列の特異値が非常に大きいまたは非常に小さい場合、...
・極端な比率の変数:ある変数が他の変数に比べて数桁大きい...
・局所的な不連続性:関数が局所的な不連続性や非線形性を持...
-[[見せかけの最適化を防ぐアルゴリズム>#nec068c7]]
--SGD (MomentumSGD, NAG)
--AdaGrad
--Rmsprop
--AdaDelta
--Adam
-勾配降下のプログラム実装
--重み更新は勾配の引き算:Θ = Θ - 勾配
--ミニバッチでは損失をΣしたものをサイズで割って平均を取る。
--この値に学習率(0.01などの値)を掛ける。
--[[個別のアルゴリズムの実装は数式より想像できる。>#nec06...
***2乗和誤差 [#o54ca9e8]
回帰の場合(ニューラルネットワークの出力と正解となる教師...
-式
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]~
[[Softmax関数>ニューラルネットワーク(推論)#b77bdfd7]]の...
---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])
# 推定データ1の誤差
yk = np.array([0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1,...
print(mean_squared_error(yk, tk))
# 推定データ2の誤差
yk = np.array([0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6,...
print(mean_squared_error(yk, tk))
--出力~
正解(tk)に対応する確率(yk)が
---高ければ高いほど、0に近いデータになる。~
tkで2が正解の場合、ykで2の確率が一番高いとしたデータの...
0.0975
---低ければ低いほど、1に近いデータになる。~
tkで2が正解の場合、ykで7の確率が一番高いとしたデータの...
0.5975
-前者の損失関数(2乗和誤差)の出力が小さい前者のykがより適...
***多クラス交差エントロピー誤差 [#p5eb632c]
多値分類(正解ラベルのykデータの底がeの自然対数 log eを計...
-式
--通常版
E = - Σ tk log yk
k
--ミニバッチ対応版
1
E = - ─ Σ Σ tnk log ynk
N n k
--説明
---log:logは底がeの自然対数 log e
---k:データの次元数
---yk:ニューラルネットワークの出力
---tk:教師データ
--例(k=10)~
[[同上>#o54ca9e8]]
-Python
--実装
"""This is a test program."""
import numpy as np
def cross_entropy_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,...
print(cross_entropy_error(yk, tk))
yk = np.array([0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6,...
print(cross_entropy_error(yk, tk))
--出力~
正解(tk)に対応する確率(yk)が
---高ければ高いほど、0に近いデータになる。~
tkで2が正解の場合、ykで2の確率が一番高いとしたデータの...
0.510825457099
---低ければ低いほど、大きいデータになる。~
tkで2が正解の場合、ykで7の確率が一番高いとしたデータの...
2.30258409299
--ミニバッチ対応版~
上記を平均にしている。
return - np.sum(tk * np.log(yk + delta)) / yk.shape[0]
-前者の損失関数(交差エントロピー誤差)の出力が小さい前者の...
***二値交差エントロピー誤差 [#uf4f7d8f]
ミニバッチ対応版
return np.mean(- y * np.log(p) - (1-y) * np.log(1-p))
**勾配の計算 [#e083729e]
[[微分(偏微分)>DS:数学的基礎 - 微分・偏微分]]で求めた...
各場所で関数の値を最も減らす方向(である可能性が高い)。
***勾配降下法 [#v7a3cd9d]
-勾配法では、広大なパラメタ空間から、複雑な[[損失関数>#l7...
最小(最大)値を出力する鞍点(saddle point)を、勾配を使...
--勾配降下法 : (誤差などが)最小になるパラメタ値を探す。
--勾配上昇法 : (確率などが)最大になるパラメタ値を探す。
-ランダムにデータを選択する場合
--1つのデータを選択する場合、[[確率的勾配降下法(SGD)>...
--n個のデータを選択し、損失の平均値を使用する場合、ミニ...
--全てのデータを選択し、損失の平均値を使用する場合、バッ...
-注意点
--勾配の指す方向に最小(最大)値があることは保証されない。
--複雑な関数の場合は、勾配の指す方向に最小(最大)値が無...
-ポイント~
学習を如何に
--効率良く進めるか。
--上手く最適解に収束させるか。
---局所最適解 ✕
---大域最適解 ○
--上手く鞍点を脱するか。
***曲線の勾配計算 [#k80130c4]
-式
df(x0, x1) df(x0, x1)
───── , ─────
dx0 dx1
--説明
---すべての変数の[[偏微分>DS:数学的基礎 - 微分・偏微分]]...
---[[上記の例>#z8297246]]なら、x0=3, x1=4の場合、勾配は、...
-Python
--実装
"""This is a test program."""
import numpy as np
def numerical_gradient(f, x01):
"""偏微分"""
h = 1e-4 # 微小な値hとして1の-4乗を用いる
grad = np.zeros_like(x01) # x01と同じ形状で要素が0。
for idx in range(x01.size):
tmp_val = x01[idx]
# 前方差分から中心差分にして誤差減
# f(x + h)
fxh1 = f(tmp_val + h)
# f(x - h)
fxh2 = f(tmp_val - h)
# (f(x + h) - f(x - h)) / 2 * h
grad[idx] = (fxh1 - fxh2) / (2 * h)
return grad
def function_2(x):
return np.sum(x**2)
print(numerical_gradient(function_2, np.array([3.0, 4.0]...
print(numerical_gradient(function_2, np.array([0.0, 2.0]...
print(numerical_gradient(function_2, np.array([3.0, 0.0]...
--出力
[ 6. 8.]
[ 0. 4.]
[ 6. 0.]
--参考~
https://github.com/oreilly-japan/deep-learning-from-scrat...
---x = -2.0 - 2.5, y = -2.0 - 2.5 の範囲の0.25刻みのメッ...
---メッシュグリッドはm行n列の配列なので、これをflatten()...
---np.array([X, Y])で x0, x1 の 2 行 m * n 列の配列にする。
---バッチ関数ではforで 1 行つづ取り出し、m * n 列のベクト...
---各場所(x0, x1)での、勾配をplt.quiver使用してベクトル...
***曲面の勾配計算 [#t9bd79ba]
-式
df(x0, x1)
x0 = x0 - η ─────
dx0
df(x0, x1)
x1 = x1 - η ─────
dx1
--説明
---上記は、一回の更新式で、勾配法では、このステップを繰り...
---ηは学習率で、一回の学習でどれだけ学習すべきか?=どれ...
---学習率は、0.01、0.001など前もって値を決める、~
それから正しく学習できているか確認しながら調整する。
-Python~
以下の式の最小値を勾配法で求める。
2 2
f(x0, x1) = x0 + x1
--実装
import numpy as np
def numerical_gradient(f, x01):
"""偏微分"""
h = 1e-4 # 微小な値hとして1の-4乗を用いる
grad = np.zeros_like(x01) # x01と同じ形状で要素が0。
# print("x01:" + str(x01));
for idx in range(x01.size):
tmp_val = x01[idx]
# 前方差分から中心差分にして誤差減
# f(x + h)
fxh1 = f(tmp_val + h)
# f(x - h)
fxh2 = f(tmp_val - h)
# (f(x + h) - f(x - h)) / 2 * h
grad[idx] = (fxh1 - fxh2) / (2 * h)
return grad
def gradient_descent(f, init_x01, lr, step_num):
print("ln : step_num = " + str(lr) + " : " + str(ste...
x01 = init_x01
for i in range(step_num):
grad = numerical_gradient(f, x01)
x01 -= lr * grad
return x01
def function_2(x):
return np.sum(x**2)
init_x = np.array([-3.0, 4.0])
print(gradient_descent(function_2, init_x, 0.1, 100))
# 学習率が大きすぎる。
init_x = np.array([-3.0, 4.0])
print(gradient_descent(function_2, init_x, 10.0, 100))
# 学習率が小さすぎる。
init_x = np.array([-3.0, 4.0])
print(gradient_descent(function_2, init_x, 1e-10, 100))
--出力
ln : step_num = 0.1 : 100
[ -6.11110793e-10 8.14814391e-10]
ln : step_num = 10.0 : 100
[ -1.91613251e+13 -1.26893162e+12]
ln : step_num = 1e-10 : 100
[-2.99999994 3.99999992]
***NNに対する勾配 [#p1598e1c]
ニューラルネットワークの学習における勾配は、~
重みパラメタに関する[[損失関数>#l7995afd]]の勾配となる。
-式
┌ w11 w21 vw31 ┐
W = │ │
└ w12 w22 vw32 ┘
┌ dL dL dL ┐
│ ── ── ── │
dL │ dw11 dw21 dw31 │
── =│ │
dW │ dL dL dL │
│ ── ── ── │
└ dw12 dw22 dw32 ┘
-Python~
--gradient_simplenet.py~
https://github.com/oreilly-japan/deep-learning-from-scrat...
---重みパラメタをインスタンス変数に持つ。~
2 行 3 列の行列で、標準正規分布関数に従う乱数を生成
---x = 入力データ, t = 正解ラベル
---predict(x)メソッド : [[dot product(ドット積)>NumPy#l...
---loss(x, t)メソッド : [[損失関数>#l7995afd]](の値を求...
predict ---> softmax ---> cross_entropy_error
>
+predict(推論する)
+softmax([[Softmax関数>ニューラルネットワーク(推論)#b77...
+cross_entropy_error([[交差エントロピー誤差>#p5eb632c]])
---nditerで多次元配列に対応した勾配の計算メソッド : commo...
https://github.com/oreilly-japan/deep-learning-from-scrat...
--実行~
フォルダ構成を維持した状態でch04に定義した以下のファイル...
C:\deep-learning-from-scratch-master\ch04>python Untitle...
--simpleNetを使って推論/学習
---実装
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルを...
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradient
from gradient_simplenet import simpleNet
print("=================================================...
print("=================================================...
net = simpleNet()
print("W:" + str(net.W))
x = np.array([0.6, 0.9])
p = net.predict(x)
print("p:" + str(p))
t = np.array([0, 0, 1])
l = net.loss(x, t)
print("loss:" + str(l))
---出力~
W:[[ 1.92087598 0.63971089 -0.26820797]
[ 0.58411529 -0.04610929 -0.88999594]]
p:[ 1.67822935 0.34232817 -0.96192113]
loss:2.92853604814
--simpleNetを使って勾配を求める
---実装
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルを...
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradient
from gradient_simplenet import simpleNet
print("=================================================...
print("=================================================...
net = simpleNet()
print("W:" + str(net.W))
x = np.array([0.6, 0.9])
t = np.array([0, 0, 1])
f = lambda w: net.loss(x, t)
dW = numerical_gradient(f, net.W)
print("dW:" + str(dW))
---出力~
==================================================
==================================================
W:[[ 1.83160192 0.4900981 -0.94188042]
[-0.24946104 2.91410946 -0.00695892]]
dW:[[ 0.06708443 0.51711391 -0.58419835]
[ 0.10062665 0.77567087 -0.87629752]]
-Wは、
W : [[ w11 = 1.83160192 w21 = 0.4900981 w31 = -0.9...
[ w12 = -0.24946104 w22 = 2.91410946 w32 = -0.0...
dL/dW : [[ dL/dw11 = 0.06708443 dL/dw21 = 0.51711391 dL/...
[ dL/dw12 = 0.10062665 dL/dw22 = 0.77567087 dL/...
--w11を h 増やすと、0.06708443 h 増加する。
--w12を h 増やすと、0.10062665 h 増加する。
--w21を h 増やすと、0.51711391 h 増加する。
--w22を h 増やすと、0.77567087 h 増加する。
--w31を h 増やすと、-0.58419835 h 増加する( = 減少する)。
--w32を h 増やすと、-0.87629752 h 増加する( = 減少する)。
--勾配がプラスならhをマイナス方向に、マイナスならプラス方...
***見せかけの最適化を防ぐ [#nec068c7]
-停留点は、極大点、極小点、鞍点のいずれかになりうる。
--鞍点は、ある次元では最小だが、別の次元では最大(最小で...
--最小化問題において、極小点は局所最小点または大域的最小...
--(最大化問題において、極大点は局所最大点または大域的最...
-学習率を大きく設定し、適切なタイミングで値を小さくしてい...
[[SGD (MomentumSGD, NAG)、AdaGrad、Rmsprop、AdaDelta、Ada...
**ミニバッチ学習 [#h15bc15d]
-平均を取って誤差逆伝播する。
-ミニバッチがランダムにサンプリングされている限り、~
ミニバッチから平均として算出された損失の勾配が真の勾配に...
***バッチ、ミニバッチ、オンライン学習 [#g72434c9]
-バッチ学習(一括学習)
--全てのサンプルを一度に用いて[[勾配>#e083729e]]を求める...
--機械学習のアルゴリズムでは基本的にバッチ学習が採用され...
--ただし、深層学習では、データが多過ぎるため、現実的でな...
-オンライン学習(逐次学習)
--ひとつのサンプルのみを用いて[[勾配>#e083729e]]を求める...
--ノイズや外れ値の影響を受け易く、解が適切な値に収束し難...
-ミニバッチ学習~
データを幾つかの塊に小分けにして、その塊毎に[[勾配>#e0837...
--[[勾配>#e083729e]]計算に損失関数の平均値を使用しても問...
--バッチ学習とオンライン学習の折衷案で、多くの場合におい...
---バッチ学習ほど学習時間がかからず、
---オンライン学習ほど解の収束が不安定にならない。
||バッチ学習(一括学習)|ミニバッチ学習|オンライン学習(...
|効率|✕|○|◎|
|安定性|◎|○|✕|
***ミニバッチ学習を訓練用データセットに適用 [#k8f7bcb2]
-ミニバッチ学習では、上記の損失関数を訓練用データセットに...
-ここでは、訓練用データセットに対する損失関数の総和を指標...
-式
E = -1/N ΣΣ tnk log ynk
n k
--説明
---[[交差エントロピー誤差>#p5eb632c]]の式をN個のデータを...
---最後に、Nで割って正規化する(データ1個あたりの平均の...
--例([[MNISTデータセット>ニューラルネットワーク(推論)#...
-Python
--実装
---one-hot表現の場合
"""This is a test program."""
import numpy as np
def mean_squared_error(ynk, tnk):
"""損失関数(交差エントロピー誤差)"""
print("tnk:" + str(tnk))
print("ynk:" + str(ynk))
batch_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 +...
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....
[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...
YNK = np.array([[0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 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...
---one-hot表現でない場合
"""This is a test program."""
import numpy as np
def mean_squared_error(ynk, tnk):
"""損失関数(交差エントロピー誤差)"""
print("tnk:" + str(tnk))
print("ynk:" + str(ynk))
batch_size = ynk.shape[0]
print("batch_size:" + str(batch_size))
delta = 1e-7 # log(0)はマイナス∞になるのを微小な値を...
ynk = ynk + delta
print("arange:" + str(ynk[np.arange(batch_size), tnk...
return - 1 / batch_size * (np.sum(np.log(ynk[np.aran...
TNK = np.array([2, 2])
YNK = np.array([[0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 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...
YNK = np.array([[0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 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...
--出力~
[[同上>#p5eb632c]]
***バッチサイズ、イテレーション数、エポック数 [#t183c375]
-バッチサイズ
--ミニバッチ[[勾配降下法>#v7a3cd9d]]のサブセットのサイズ
--訓練データサイズをバッチサイズで割った値
--1,000件の訓練データでバッチサイズを200にすると、~
サブセットのサイズは200件でバッチの回数は5回になる。
-イテレーション数
--前述の訓練データ中のバッチ回数がイテレーション数
--訓練データサイズとバッチサイズが決まれば自動的に決まる。
-エポック数
--一つの訓練データを何回繰り返して学習させるか?
--深層学習ではパラメタが収束するまで同じ訓練データで繰り...
--学習回数(エポック数)を一定以上増加させると、過学習が...
-参考~
機械学習/ディープラーニングにおける~
バッチサイズ、イテレーション数、エポック数の決め方 - Qiita~
https://qiita.com/kenta1984/items/bad75a37d552510e4682
***適切なバッチサイズの選択 [#a85f1623]
-適切なバッチサイズを選ぶ事が、学習を上手く行うために必要...
--大きくした場合
---大まかな特徴を捉えるため精度は下がる。
---パラメタの更新が少ないため計算コストは下がる。
--小さくした場合
---精度は上がる。小さすぎると学習が終了しない可能性がある。
---1件毎に誤差逆伝播処理するため計算回数=コストは上がる。
--その他注意点
---GPU を用いて計算する際は、2 のべき乗にバッチサイズを設...
---バイアスがかからないようにミニバッチはランダムに選ぶ。
-CNNでの学習例~
[[バッチサイズ500のままエポック数を増やせば>#t183c375]]よ...
--バッチサイズ5
---そもそも学習が上手くできていない。
---1つ1つのデータに敏感に反応し過ぎて学習が難しい。
--バッチサイズ50
---初めは順調に学習が進む。
---途中から過学習を起こす。
--バッチサイズ500
---過学習を起こすことなく順調に学習が進むが、
---パラメタ更新回数が少ないため、学習は途中
>※loss(損失)とacc(正解率)の進捗を確認する。
**その他 [#d6a259c8]
***[[深層学習の誤差逆伝播法]] [#c4daa80e]
***[[深層学習のテクニック]] [#j9845af7]
*実装 [#i08ec171]
**手順 [#o2a66edf]
***前提 [#a0ba9a39]
-ニューラルネットワークには適応可能な重みとバイアスがある。
-学習により、この重みとバイアスを訓練データに適応するよう...
-ニューラルネットワークの学習は、以下の4つのステップで行...
***ステップ 1 [#u61466c2]
-訓練データから、ランダムにデータを選択する。
-ここでは、損失関数の値を減らすことを目的とする。
***ステップ 2 [#lf9098f7]
-ミニバッチの損失関数を減らすために、各重みパラメタの[[勾...
-[[勾配>#e083729e]]は、損失関数の値を最も減らす方向を示す。
***ステップ 3 [#k7dba9a3]
重みパラメタを[[勾配>#e083729e]]の方向に微小量だけ更新す...
***ステップ 4 [#b640b624]
[[ステップ 1>#u61466c2]], [[ステップ 2>#lf9098f7]], [[ス...
**2層NNのクラス [#p0fb2d58]
TwoLayerNetクラス~
https://github.com/oreilly-japan/deep-learning-from-scrat...
***変数 [#ybae532d]
|#|>|変数|説明|h
|1|>|params|ニューラルネットワークの重みパラメタのディク...
|1-1||params['W1']|第1層の重み|
|1-2||params['b1']|第1層のバイアス|
|1-3||params['W2']|第2層の重み|
|1-4||params['b2']|第2層のバイアス|
|2|>|grads|numerical_gradientで計算された勾配を保持するデ...
|1-1||params['W1']|第1層の重みの勾配|
|1-2||params['b1']|第1層のバイアスの勾配|
|1-3||params['W2']|第2層の重みの勾配|
|1-4||params['b2']|第2層のバイアスの勾配|
***メソッド [#p6711ebd]
|#|メソッド シグネチャ|引数|説明|h
|1|>|__init__(self, input_size, hidden_size, output_size,...
|1-1||self|インスタンス|
|1-2||input_size|入力層のニューロンの数|
|1-3||hidden_size|隠れニューロンの数|
|1-4||output_size|出力層のニューロンの数|
|1-5||weight_init_std|・・・|
|2|>|predict(self, x):|推論を行う|
|2-1||self|インスタンス|
|2-2||x|画像データ|
|3|>|loss(self, x, t):|損失関数の値を求める|
|3-1||self|インスタンス|
|3-2||x|画像データ|
|3-3||t|正解ラベル|
|4|>|accuracy(self, x, t):|推論の精度を求める|
|4-1||self|インスタンス|
|4-2||x|画像データ|
|4-3||t|正解ラベル|
|5|>|numerical_gradient(self, x, t):|lossを使用し各重みパ...
|5-1||self|インスタンス|
|5-2||x|画像データ|
|5-3||t|正解ラベル|
|6|>|gradient(self, x, t):|numerical_gradientの高速版|
|6-1||self|インスタンス|
|6-2||x|画像データ|
|6-3||t|正解ラベル|
***学習過程の実装 [#x4872920]
[[勾配法>#v7a3cd9d]]により[[(損失)関数>#l7995afd]]を少...
-式~
[[コチラ>ニューラルネットワーク(推論)#laa37ea3]]と、[[...
--第1層 (100個のバッチ)
---x(1) =
(100, 784 = 28 * 28 pixel)
--重みパラメタ
---W(1) =
(784, x = 100)
---b(1) =
(1, x = 100)
--隠れ層 (x = 100)
---A(1) =
(100, x = 100)
---= x(2) =
(100, x = 100)
--重みパラメタ
---W(2) =
(x = 100, 10)
---b(2) =
(1, 10)
--第2層
---A(2) =
(100, 10) # 0-9の数字
-Python~
https://github.com/oreilly-japan/deep-learning-from-scrat...
--実装~
C:\deep-learning-from-scratch-master\ch04\train_neuralne...
~
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルを...
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normal...
network = TwoLayerNet(input_size=784, hidden_size=50, ou...
iters_num = 10000 # 繰り返しの回数を適宜設定する
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1
train_loss_list = []
for i in range(iters_num):
print(str(i) + " / " + str(iters_num))
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
# 勾配の計算
#grad = network.numerical_gradient(x_batch, t_batch)
grad = network.gradient(x_batch, t_batch)
# パラメータの更新
for key in ('W1', 'b1', 'W2', 'b2'):
network.params[key] -= learning_rate * grad[key]
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
plt.xlabel("Iteration")
plt.ylabel("loss")
plt.plot(range(iters_num), train_loss_list)
plt.show()
--実行~
フォルダ構成を維持した状態でch04に定義した上記ファイルを...
C:\deep-learning-from-scratch-master\ch04>python train_n...
--出力~
---CMD
0 / 10000
...
9999 / 10000
---グラフ
#ref(learning.png,left,nowrap,学習結果,60%)
***学習結果を確認する実装 [#ve66f150]
学習結果を使用して、学習データとテストデータを推論する。
-Python~
https://github.com/oreilly-japan/deep-learning-from-scrat...
--実装~
C:\deep-learning-from-scratch-master\ch04\train_neuralne...
--実行~
フォルダ構成を維持した状態でch04に定義した上記ファイルを...
C:\deep-learning-from-scratch-master\ch04>python train_n...
--出力~
1バッチ・サイクル毎に学習した重みパラメタを使用した推論結...
---CMD
train acc, test acc | 0.102183333333, 0.101
train acc, test acc | 0.783416666667, 0.7894
train acc, test acc | 0.874916666667, 0.8791
train acc, test acc | 0.8964, 0.8991
train acc, test acc | 0.907433333333, 0.9092
train acc, test acc | 0.913616666667, 0.9147
train acc, test acc | 0.9184, 0.9185
train acc, test acc | 0.923366666667, 0.9238
train acc, test acc | 0.926316666667, 0.9275
train acc, test acc | 0.9294, 0.9298
train acc, test acc | 0.932666666667, 0.9318
train acc, test acc | 0.9341, 0.9341
train acc, test acc | 0.936816666667, 0.9367
train acc, test acc | 0.940133333333, 0.9382
train acc, test acc | 0.94175, 0.9397
train acc, test acc | 0.943566666667, 0.9417
train acc, test acc | 0.945233333333, 0.9435
---グラフ
#ref(accuracy.png,left,nowrap,学習後の推論結果,60%)
***ハイパーパラメタ [#y43c81d1]
-人間が手動で設定するパラメタ
--[[確率的勾配降下法(SGD)>深層学習のテクニック#o2fe1f26...
iters_num = 10000
--1回のミニバッチのサイズ
batch_size = 100
--学習率
learning_rate = 0.1
-NNの構造に組み込まれているハイパーパラメタ
--層のサイズ
--層の深さ
ページ名: