ギークなエンジニアを目指す男

機械学習系の知識を蓄えようとするブログ

ゼロから作るDeepLearning 4章を学ぶ その2

前回に引き続き、4章で学んだことを残しておきます。

前回記事

taxa-program.hatenablog.com

ニューラルネットワークでの勾配

ニューラルネットワークでも勾配を求める必要があります。
その時、対象となる関数は......
そう、損失関数ですね。この損失関数の最小値を求めたいのです。

実際にコードを見てみます。

# coding:utf-8
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

class simpleNet:
    # コンストラクタ
    def __init__(self):
        # インスタンス変数の初期化 2*3の重みパラメータ
        self.W = np.random.randn(2,3) # ガウス分布(平均0、標準偏差1)で重みを初期化

    # 予測
    def predict(self, x):
        return np.dot(x, self.W)

    # 損失関数(交差エントロピー)
    def loss(self, x, t):
        z = self.predict(x)
        y = softmax(z)
        loss = cross_entropy_error(y, t)
        return loss

# ネットワークを構築(2*3)
net = simpleNet()
# 正解ラベルの設定
t = np.array([0, 0, 1])
# 勾配を求める
f = lambda w: net.loss(x, t)
dW = numerical_gradient(f, net.W)
np.set_printoptions(precision=5, suppress=True) # 指数表示の禁止
print(dW)

ここでの出力は下記のようになりました。
(実際はガウス分布で初期化される値によって、表示される値は異なります)

[ 5.96015 0.00023 -5.96038]
[ 0.89402 0.00003 -0.89406]

これは、w11(重み1-1番目)をhだけ増加させると、損失関数の値は5.9hだけ増加するということを意味しています。(マイナスの値はその分減少するということ)

勾配が大きいほど、損失関数を0に近づける貢献度も高いはずです。

したがって、この損失関数の値を小さくするには、
w11 → マイナス方向へ更新
w12 → マイナス方向へ更新
w13 → プラス方向へ更新
w21 →マイナス方向へ更新
w22 → マイナス方向へ更新
w23 → プラス方向へ更新
すれば、徐々に小さくなりそうですね。

ニューラルネットワークの学習手順を復習

前提
ニューラルネットワークには、適応可能な重みバイアスがあり、この重みバイアスを訓練データに適応するように調整することを「学習」と呼びました。
学習は下記4STEPで実行することができます。

  • STEP1(ミニバッチ)
    訓練データの中からランダムに一部のデータを選出する。選出されたデータをミニバッチと呼び、そのミニバッチの損失関数の値を減らすことをモチベーションとする。

  • STEP2(勾配の算出)
    ミニバッチの損失関数を減らすために、各重みパラメータの勾配を求める。勾配は、損失関数の値を最も減らす方向を示すベクトルである。

  • STEP3(パラメータの更新)
    重みパラメータを勾配方向に微少量だけ更新する。更新する度合いを学習率と呼ぶ。

  • STEP4(繰り返す)
    STEP1~STEP3を繰り返す。

次はニューラルネットワークの構築に入ります。
長くなりそうなため、別記事にてまとめます。