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

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

2024年度前期輪読会#8「ゼロから作る Deep Learning」
５章 誤差逆伝播法 5.5～5.6
京都大学経済学部二回生 大澤衡正
0


# Page. 2

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

誤差逆伝播法
目次
1. ReLUレイヤの逆伝播
2. Sigmoidレイヤの逆伝播
3. Affineレイヤの逆伝播
4. Softmax-with-Lossレイヤの逆伝播
5. まとめ
1


# Page. 3

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

1. ReLUレイヤの逆伝播
2


# Page. 4

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

1 . ReLUレイヤの逆伝播
計算グラフ
●
ReLUの微分は
𝜕𝑥
= 1(x &gt; 0)
𝜕𝑦
𝜕𝑥
= 0(x ≤ 0)
𝜕𝑦
よって、逆伝播時の入力ｘが０より大きければそれを
そのまま流し、それ以外の場合は下流への信号はスト
ップする。
3


# Page. 5

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

2. ReLUレイヤの逆伝播
実装
class Relu:
def __init__(self) -&gt; None:
# 準伝播時の入力値が0以下の要素をTrueとする配列
self.mask: npt.NDArray[np.bool] = np.zeros(0)
def forward(self, x: npt.NDArray[np.float64]) -&gt; npt.NDArray[np.float64]:
self.mask = x &lt;= 0
out = x.copy()
out[self.mask] = 0
return out
def backward(
self, dout: npt.NDArray[np.float64]
) -&gt; npt.NDArray[np.float64]:
# 逆伝播時に0以下の要素を0にする
dout[self.mask] = 0
dx = dout
return dx
4


# Page. 6

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

2. Sigmoidレイヤの逆伝播
5


# Page. 7

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

2. Sigmoidレイヤの逆伝播
計算グラフ
Sigmoid関数の計算グラフは上に示した通り
これはさらに簡略化できて
𝜕𝐿
y(1 − y)
𝜕𝑦
よってSigmoid関数の逆伝播は順伝播の出力だけで書く
ことができる
6


# Page. 8

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

2. . Sigmoidレイヤの逆伝播
実装
class Sigmoid:
def __init__(self) -&gt; None:
self.out: npt.NDArray[np.float64] = np.zeros(0)
def forward(self, x: npt.NDArray[np.float64]) -&gt; npt.NDArray[np.float64]:
out = 1.0 / (1.0 + np.exp(-x))
self.out = out
return out
def backward(
self, dout: npt.NDArray[np.float64]
) -&gt; npt.NDArray[np.float64]:
dx = dout * (1.0 - self.out) * self.out
return dx
7


# Page. 9

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

3. Affineレイヤの逆伝播
8


# Page. 10

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

2. Affineレイヤの逆伝播
計算グラフ
←Affineレイヤの計算グラフ
これまでの計算グラフではノー
ドを流れるのはスカラ値だった
が、今回は行列が流れる
※Nはbatchサイズを意味する
式1.2の導出は以下が参考になる
行列積の勾配を誤差逆伝播法により求める (zenn.dev)
9


# Page. 11

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

2. Affineレイヤの逆伝播
実装
class Affine:
def __init__(
self, W: npt.NDArray[np.float64], b: npt.NDArray[np.float64]
) -&gt; None:
self.W: npt.NDArray[np.float64] = W
self.b: npt.NDArray[np.float64] = b
self.x: npt.NDArray[np.float64] = np.zeros(0)
self.dW: npt.NDArray[np.float64] = np.zeros(0)
self.db: npt.NDArray[np.float64] = np.zeros(0)
def forward(self, x: npt.NDArray[np.float64]) -&gt; npt.NDArray[np.float64]:
self.x = x
out = np.dot(x, self.W) + self.b
return out
def backward(
self, dout: npt.NDArray[np.float64]
) -&gt; npt.NDArray[np.float64]:
dx = np.dot(dout, self.W.T)
# x方向以外の微分も求める
self.dW = np.dot(self.x.T, dout)
self.db = np.sum(dout, axis=0)
return dx
10


# Page. 12

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

４. Softmax-with-Lossレイヤの逆伝播
11


# Page. 13

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

2. Softmax-with-Lossレイヤの逆伝播
計算グラフ
●
Softmax関数の損失関数として交差エント
ロピー誤差を用いると逆伝播は
(y1 − t1, y2 − t2, y3 − t3)
という綺麗な値になる。これは偶然ではなく、
交差エントロピー誤差が望ましい性質を持つよ
うに設計されているから
また、単に綺麗なだけでなく、教師ラベルとNN
の予測の差が出力されていることも重要
※ここでは３クラス分類を行う場合を想定
12


# Page. 14

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

2. Softmax-with-Lossレイヤの逆伝播
計算グラフの詳細
softmax関数の計算グラフ
クロスエントロピー誤差
の計算グラフ
13


# Page. 15

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

2. ReLUレイヤの逆伝播
実装
class SoftmaxWithLoss:
def __init__(self) -&gt; None:
self.loss: float = 0.0
self.y: npt.NDArray[np.float64] = np.zeros(0)
self.t: npt.NDArray[np.float64] = np.zeros(0)
def forward(
self, x: npt.NDArray[np.float64], t: npt.NDArray[np.float64]
) -&gt; float:
self.t = t
self.y = softmax(x)
self.loss = float(cross_entropy_error(self.y, self.t))
return self.loss
def backward(self, dout: float = 1) -&gt; npt.NDArray[np.float64]:
batch_size = self.t.shape[0]
# バッチサイズで割ることで、1サンプルあたりの誤差を求める
dx = (self.y - self.t) / batch_size
return dx
14


# Page. 16

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

誤差逆伝播法
4.まとめ
まとめ１
まとめ２
まとめ３
NNを構成するレイヤーを一つのノードとみなして誤差逆伝播を実装できる
クロスエントロピー誤差はSoftmax関数と組み合わせたときに逆伝播の値
が正確にモデルの予測誤差を反映した簡潔な値となるように設計されている
各層の準伝播と逆伝播を一つのクラスとして実装することで、実際
のコーディングを簡潔に行うことができる
15


# Page. 17

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

16


