---
title: 【ゼロから作るDeep Learning】5.7~5.8
tags: 
author: [京都大学人工知能研究会KaiRA](https://convert.docswell.com/user/kyoto-kaira)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/57G3ZV6XJL.jpg?width=480
description: 【ゼロから作るDeep Learning】5.7~5.8 by 京都大学人工知能研究会KaiRA
published: June 23, 24
canonical: https://convert.docswell.com/s/kyoto-kaira/5249N4-2024-06-23-223026
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/57G3ZV6XJL.jpg)

2024 前期輪読会 # 8
ゼロから作るDeep Learning 5.7~5.8
工学部 4回生 河田賢斗
0


# Page. 2

![Page Image](https://bcdn.docswell.com/page/4EQ5L645JP.jpg)

5.7.1 ニューラルネットワークの学習の全体図
[前提]
ニューラルネットワーク(以下NN)は、適応可能な重みとバイアス
を有する。訓練データに適応するように調整すること = 「学習」
[学習の手順]
Step1(ミニバッチ)
: 訓練データの中からランダムに一部のデータを抽出
Step2(勾配の算出)
: 各重みパラメータに関する損失関数の勾配を算出
Step3(パラメータの更新)
: 重みパラメータを勾配方向に微小量だけ更新
Step4(繰り返し)
: Step1 ～Step3を繰り返す
1


# Page. 3

![Page Image](https://bcdn.docswell.com/page/KJ49D4QV71.jpg)

5.7.2 誤差逆伝播法に対応したNNの実装
ポイント :
レイヤを使用することでpredict()やgradient()の処理がレイヤ
の伝播だけで達成可能
２層 NN の場合 → class TwoLayerNet を参考にレイヤを追加
# レイヤの生成
self.layers = OrderedDict()
self.layers[&#039;Affine1&#039;] = Affine(self.params[&#039;W1&#039;], self.params[&#039;b1&#039;])
self.layers[&#039;Relu1&#039;] = Relu()
self.layers[&#039;Affine2&#039;] = Affine(self.params[&#039;W2&#039;], self.params[&#039;b2&#039;])
self.lastLayer = SoftmaxWithLoss()
→次のページへ続く
2


# Page. 4

![Page Image](https://bcdn.docswell.com/page/LE1KZ4P4JG.jpg)

5.7.2 誤差逆伝播法に対応したNNの実装
self.layers = OrderDict()として、NNのレイヤを保存する(順番つきのdictionary)
→ディクショナリに追加した要素の順番を記憶可能
順伝播では、追加した順にレイヤのforward()メソッドを呼び出せばよい
逆伝播では、逆の順番でレイヤを呼び出せばよい
ここでは、Affine1、Relu1、Affine2、SoftmaxwithLossレイヤが各々の内部で順
伝播・逆伝播を正しく処理してくれるため、これらのレイヤを正しい順番で連結し、
順番にレイヤを呼び出せばよい
def predict(self, x):
for layer in self.layers.values():
認識(推論)を行う。
順伝播によって出力xを得る。
x = layer.forward(x)
return x
3


# Page. 5

![Page Image](https://bcdn.docswell.com/page/GEWD9X2ZJ2.jpg)

5.7.2 誤差逆伝播法に対応したNNの実装
def gradient(self, x, t):
# forward
順伝播によって損失関
数の値を求める
self.loss(x, t)
# backward
dout = 1 !
dout = self.lastLayer.backward(dout)
初期値を1と設定し、逆伝播
によって差分誤差を求める
layers = list(self.layers.values())
layers.reverse()
! reverseメソッドの定義
for layer in layers:
dout = layer.backward(dout)
上で求まったdout(差分誤差）が前レイに伝わる。
すなわち、AffineレイヤやReluレイヤにて逆伝播さ
れる。Backwardに記載の事柄が実行される。
4


# Page. 6

![Page Image](https://bcdn.docswell.com/page/47ZG96DLE3.jpg)

5.7.2 誤差逆伝播法に対応したNNの実装
・上でみたコードは、誤差逆伝播法にて用いられるものである
・その他は、2層の NN を実現するためのコード
( class TwoLayerNet に記載のコード)を利用している
NN の構成要素をレイヤとして実装したことで、NN を簡単に構築
することが出来る
→各レイヤ内で実装された順伝播・逆伝播によって学習に必要な勾
配が求まる
5


# Page. 7

![Page Image](https://bcdn.docswell.com/page/YJ6YK21M7V.jpg)

勾配を算出する2つの手法
数値微分
解析的手法
欠点)
・計算に時間を要する
利点)
・実装が容易→ミスが少ない
欠点)
微小な差分により、微分を求
める
・計算が高速かつ効率的
ex.)
def numerical_diff(f, x) :
h = 1e-4
return (f(x + h) – f(x-h))
/(2*h)
・実装がやや複雑→ミスが多い
利点)
数式から解析的に微分を求めるため、
誤差が含まれない「真の微分」
誤差逆伝播法で使用される
数値微分の結果と誤差伝播法の結
果を比較して、誤差伝播法の実装
の正しさを実証する→「勾配確認」
6


# Page. 8

![Page Image](https://bcdn.docswell.com/page/GJ5GP24QJ4.jpg)

5.7.3 誤差逆伝播法の勾配確認
以下に、勾配確認の実装を示す
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定
import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True,
one_hot_label=True)
7


# Page. 9

![Page Image](https://bcdn.docswell.com/page/9E2Y64VWER.jpg)

5.7.3 誤差逆伝播法の勾配確認
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
x_batch = x_train[:3]
t_batch = t_train[:3]
grad_numerical = network.numerical_gradient(x_batch, t_batch)
grad_backprop = network.gradient(x_batch, t_batch)
for key in grad_numerical.keys():
diff = np.average( np.abs(grad_backprop[key] - grad_numerical[key]) )
print(key + &quot;:&quot; + str(diff))
参照 : https://github.com/oreilly-japan/deep-learning-fromscratch/blob/master/ch05/gradient_check.py
8


# Page. 10

![Page Image](https://bcdn.docswell.com/page/D7YG9M397M.jpg)

5.7.3 誤差逆伝播法の勾配確認
データの読み込みでは、MNISTデータセットを読み込む
X_batch、t_batchを定義し、訓練データの一部を抽出する
grad_numerical(数値微分の値)及びgrad_backprop(逆誤差伝
播法での微分の値)を定義し、誤差を確認する
(各重みパラメータにおいて差の絶対値を求め、平均を算出)
算出した値が0になることは稀であるが、十分に小さな値をとる
とき(1.0*e-12など)、誤差逆伝播法の実装に誤りが無いことの
信憑性が増す
9


# Page. 11

![Page Image](https://bcdn.docswell.com/page/VENGLWVDJ8.jpg)

5.7.4 誤差逆伝播法を使った学習
以下に、誤差逆伝播法を用いた NN の学習の実装を示す
# coding: utf-8
import sys, os
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet
# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True,
one_hot_label=True)
10


# Page. 12

![Page Image](https://bcdn.docswell.com/page/Y79W4X6873.jpg)

5.7.4 誤差逆伝播法を使った学習
network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
iters_num = 10000
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1
train_loss_list = []
train_acc_list = []
test_acc_list = []
iter_per_epoch = max(train_size / batch_size, 1)
11


# Page. 13

![Page Image](https://bcdn.docswell.com/page/G78NQ2ZZJD.jpg)

5.7.4 誤差逆伝播法を使った学習
for i in range(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 (&#039;W1&#039;, &#039;b1&#039;, &#039;W2&#039;, &#039;b2&#039;):
network.params[key] -= learning_rate * grad[key]
12


# Page. 14

![Page Image](https://bcdn.docswell.com/page/L7LPX2D1JR.jpg)

5.7.4 誤差逆伝播法を使った学習
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
if i % iter_per_epoch == 0:
train_acc = network.accuracy(x_train, t_train)
test_acc = network.accuracy(x_test, t_test)
train_acc_list.append(train_acc)
test_acc_list.append(test_acc)
print(train_acc, test_acc)
参照 : https://github.com/oreilly-japan/deep-learning-fromscratch/blob/master/ch05/train_neuralnet.py
13


# Page. 15

![Page Image](https://bcdn.docswell.com/page/4EM4L8P5JW.jpg)

5.8 まとめ
本章では、視覚的に計算過程を表す計算グラフを学んだ
計算グラフを描く
局所的な微分(NNでの誤差逆伝播法)
NNの処理をレイヤで実装する→
Softmaxレイヤ、Affineレイヤ、Softmax-with-Lossレイヤ
ReLUレイヤ
各レイヤには、backward・forwardのメソッドが実装されており、
データを逆方向・順方向に伝播させることが出来る
重みパラメータの勾配を効率的に求めることが可能
さらに、レイヤの重ね合わせで任意のNNを構築することも可能
14


# Page. 16

![Page Image](https://bcdn.docswell.com/page/PERWK51ZJ9.jpg)

15


# Page. 17

![Page Image](https://bcdn.docswell.com/page/P7XPLKY1JX.jpg)

16


# Page. 18

![Page Image](https://bcdn.docswell.com/page/37KDL53MED.jpg)

17


