3章ではニューラルネットワークの「推論」を実装したが、4章からニューラルネットワークの「学習」を実装する。
「学習」とは:訓練データから最適な重みパラメータ値を自動で獲得すること
パラメータの数は、実際数千〜数億にも及ぶため、手動で調整することは不可能
「データ駆動アプローチ」:いままでの「人」を中心としたアプローチではなく、「データ」を中心としたアプローチ
ニューラルネットワークやディープラーニングでは、従来の機械学習以上に、属人性を排している
・機械学習(ML)以前 入力データ → 人力処理 → 出力データ
↓
・ML 入力データ → 人力特徴量 → ML自動処理 → 出力データ
↓
・NNやDL 入力データ → NN/DL自動処理 → 出力データ
機械学習におけるデータの取扱について
2種類のデータ:「訓練(教師)データ」と「テストデータ」
まず「訓練(教師)データ」で学習し、最適なパラメータを探索
つぎに「テストデータ」で汎化能力を評価し、一部のデータセットだけ過度に対応した「過学習overfitting」を避ける
「損失関数loss function」:ニューラルネットワークの学習で用いられる指標で、主に「二乗和誤差」「交差エントロピー誤差」が用いられる
「二乗和誤差」について。
def mean_squared_error(y, t):
return np.sum( (y - t)**2 ) / 2
import numpy as np
import my_module as my
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print(np.sum(y))
y = my.mean_squared_error(np.array(y), np.array(t))
print(y)
y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print(np.sum(y))
y = my.mean_squared_error(np.array(y), np.array(t))
print(y)
「交差エントロピー誤差」について。
def cross_entropy_error(y, t):
delta = 1e-7
return - np.sum( t * np.log( y + delta ) )
import numpy as np
import my_module as my
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print(np.sum(y))
y = my.cross_entropy_error(np.array(y), np.array(t))
print(y)
y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print(np.sum(y))
y = my.cross_entropy_error(np.array(y), np.array(t))
print(y)
続いて、大量にある全データのうち一部を選出して近似とする「ミニバッチ学習」について。
>>> import numpy as np
>>> np.random.choice(60000, 10)
array([54904, 15528, 35786, 44249, 25077, 37764, 46607, 552, 33463, 12885])
>>> np.random.choice(60000, 10)
array([38745, 8181, 8602, 37811, 24747, 18214, 50371, 13052, 13100, 36289])
>>> np.random.choice(60000, 10)
MNISTデータセットで動作確認
import sys, os
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
(x_train, t_train), (x_test, t_test) = \
load_mnist(normalize=True, one_hot_label=True)
print(x_train.shape)
print(t_train.shape)
train_size = x_train.shape[0]
batch_size = 10
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
print(x_batch)
'''
[[ 0. 0. 0. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 0. 0. 0.]
...,
[ 0. 0. 0. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 0. 0. 0.]]
'''
print(t_batch)
'''
[[ 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
[ 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
[ 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
'''
def cross_entropy_error_batch(y, t):
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
batch_size = y.shape[0]
return - ( np.sum( t * np.log( y ) ) / batch_size )
def cross_entropy_error_batch_label(y, t):
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
batch_size = y.shape[0]
return - ( np.sum( t * np.log( y[np.arange(batch_size), t] ) ) / batch_size )
ニューラルネットワークの学習では、
認識精度を「指標」にしてはいけない。
なぜなら、認識精度を指標にすると、
パラメータの微分がほとんどの場所で0
になってしまうから。
だから、損失関数が必要なのである。