-
Notifications
You must be signed in to change notification settings - Fork 0
DNET_NeuralNetworkInference
- 戻る(深層学習(deep learning))
- パーセプトロン
-
ニューラルネットワーク
- ニューラルネットワーク(推論)
- ニューラルネットワーク(学習)
推論フェーズでは、信号は順方向に伝播する。
バイアスと活性化関数を省略し重みだけとする。
X行列 * W行列=Y行列
┌ ┐ ┌ ┐ ┌ ┐
│a1 b1│ │a2 b2 c2│ = │a1a2+b1d2 a1b2+b1e2 a1c2+b1f2│
└ ┘ │d2 e2 f2│ └ ┘
└ ┘
X行列 W行列 Y行列
1行2列 2行3列 1行3列
─ ─
└────┘

┌ ┐ ┌ ┐ ┌ ┐
│a b│ │1 3 5│ = │1a+2b 3a+4b 5a+6b│
└ ┘ │2 4 6│ └ ┘
└ ┘
X行列 W行列 Y行列
1行2列 2行3列 1行3列
─ ─
└──┘
>>> x=np.array([1,2])
>>> x
array([1, 2])
>>> w=np.array([[1,3,5],[2,4,6]])
>>> w
array([[1, 3, 5],
[2, 4, 6]])
>>> y=np.dot(x,w)
>>> y
array([ 5, 11, 17])前述の「簡単なニューラルネットワーク」を3層化する。

-
第一層目の計算の例
入力が1行2列、出力が1行3列-
重み付き信号とバイアスの和
- a(1)1 = w(1)11 x1 + w(1)12 x2 + b(1)1
- a(1)2 = w(1)21 x1 + w(1)22 x2 + b(1)2
- a(1)3 = w(1)31 x1 + w(1)32 x2 + b(1)3
-
これを行列で表すと、
入力が1行2列、出力が1行3列だから、A(1) = X(1) W(1) + B(1)-
X(1) = [x1 x2]
-
A(1) = [a(1)1 a(1)2 a(1)3]
-
W(1) = W(1)は、2行3列
┌ ┐ │w(1)11 w(1)21 w(1)31│ │w(1)12 w(1)22 w(1)32│ └ ┘ -
B(1) = 出力が1行3列だから、
[b(1)1 b(1)2 b(1)3] -
活性化関数
Sigmoid関数(ニューラルネットワークの該当節を参照)を使用する。h(A(1)) = Z(1)
-
-
-
第二層目の計算の例
入力が1行3列、出力が1行2列だから、-
第一層目と大方、同じ。
- X(2) = 1行3列
- A(2) = 1行2列
- W(2) = 入力が1行3列、出力が1行2列だから、W(2)は、3行2列
- b(2) = 出力と同じ、1行2列
-
-
第三層目の計算の例
入力が1行2列、出力が1行2列だから、
そのまんま実装した。
"""This is a test program."""
import numpy as np
def sigmoid(x_1):
"""sigmoid."""
return 1 / (1 + np.exp(-x_1))
def identity_function(y_1):
"""出力層の活性化関数"""
return y_1
# 第一層
X1 = np.array([1.0, 0.5])
W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
B1 = np.array([0.1, 0.2, 0.3])
print("第一層")
A1 = np.dot(X1, W1) + B1
print("A1:" + str(A1))
Z1 = sigmoid(A1)
print("Z1:" + str(Z1))
# 第二層
X2 = Z1
W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
B2 = np.array([0.1, 0.2])
print("第二層")
A2 = np.dot(X2, W2) + B2
print("A2:" + str(A2))
Z2 = sigmoid(A2)
print("Z2:" + str(Z2))
# 第三層
X3 = Z2
W3 = np.array([[0.1, 0.3], [0.2, 0.4]])
B3 = np.array([0.1, 0.2])
print("第三層")
A3 = np.dot(X3, W3) + B3
print("A3:" + str(A3))
Z3 = identity_function(A3)
print("Z3:" + str(Z3))- init_networkで、ニューラルネットワークを定義/初期化し、
- forwardで入力から出力方向への伝達処理を行う。
"""This is a test program."""
import numpy as np
def sigmoid(x_1):
"""sigmoid."""
return 1 / (1 + np.exp(-x_1))
def identity_function(y_1):
"""出力層の活性化関数"""
return y_1
def init_network():
"""ニューラルネットワーク"""
network = {}
networkw = {}
networkw[0] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
networkw[1] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
networkw[2] = np.array([[0.1, 0.3], [0.2, 0.4]])
networkb = {}
networkb[0] = np.array([0.1, 0.2, 0.3])
networkb[1] = np.array([0.1, 0.2])
networkb[2] = np.array([0.1, 0.2])
network["W"] = networkw
network["b"] = networkb
return network
def forward(network, zzz):
"""ニューラルネットワークの実行"""
tier = len(network["W"])
for num in range(tier - 1):
print("第" + str(num + 1) + "層")
xxx = zzz
aaa = np.dot(xxx, network["W"][num]) + network["b"][num]
print("A" + str(num + 1) + ":" + str(aaa))
zzz = sigmoid(aaa)
print("Z" + str(num + 1) + ":" + str(zzz))
print("第" + str(tier) + "層")
xxx = zzz
aaa = np.dot(xxx, network["W"][tier -1]) + network["b"][tier -1]
print("A" + str(tier) + ":" + str(aaa))
zzz = identity_function(aaa) # 出力層の活性化関数
print("Z" + str(tier) + ":" + str(zzz))
return zzz
print(forward(init_network(), np.array([1.0, 0.5])))-
ニューラルネットワークは
-
分類問題と
- 入力データがどのクラスに属するか?
- 例:写真から男性・女性を識別する。
-
回帰問題に
- 入力データから連続的な数値を予測する。
- 例:写真からその人の体重を予測する。
-
用いることができる。
を利用する。
-
式
f(x) = x -
特徴
- 回帰問題で使用。
- 入力をそのまま返す。
-
グラフ

- 2クラス分類の機械学習で使用される。
- xで条件付けされたyのベルヌーイ分布(統計解析の該当節を参照)を推定。
- オッズの対数を取ったロジット関数の逆関数
(統計解析のロジスティック回帰分析の節を参照)らしい。 - 中間層の活性化関数として既出なので、実装など詳細については
ニューラルネットワークの該当節を参照。
-
多クラス分類の機械学習で使用される。
-
xで条件付けされたyのマルチヌーイ分布(統計解析の該当節を参照)を推定。
-
Sigmoid関数を多クラスに拡張、一般化したもの。
-
Softmax関数の結果は
- 0 - 1 の実数になり、その総和は 1.0 になる。
- 従って、Softmax関数の結果は「確率」として解釈できる。
- これは多クラス分類問題で使用できる。
- 分類では、一番大きい値のみを使用する。
- Softmax関数を使用しても値の大小関係は変わらないので
順方向の推論フェーズにおいては、Softmax関数は省略可能である。
exp(Ak)
Yk = ───────────
n
Σexp(Ai)
i=1
Sigmoid関数(ニューラルネットワークの該当節を参照)の項で説明した通り、
- exp(x)とは、eのx乗を意味する。
- eは ネイピア数(2.7182)の実数を表す。

- そのまま実装
>>> a=np.array([0.3, 2.9, 4.0])
>>> a
array([ 0.3, 2.9, 4. ])
>>> exp_a = np.exp(a)
>>> exp_a
array([ 1.34985881, 18.17414537, 54.59815003])
>>> sum_exp_a = np.sum(exp_a)
>>> sum_exp_a
74.122154210163302
>>> y = exp_a / sum_exp_a
>>> y
array([ 0.01821127, 0.24519181, 0.73659691])
>>>- 関数化
"""This is a test program."""
import numpy as np
def softmax(aaa):
"""Softmax関数"""
exp_a = np.exp(aaa)
sum_exp_a = np.sum(exp_a)
return exp_a / sum_exp_a
print(softmax(np.array([0.3, 2.9, 4.0])))Softmax関数は指数関数を使用するため、オーバーフローし易い。
従って、ここでは、オーバーフロー対策について考える。
- 以下のように変形できる。
exp(Ak)
Yk = ───────────
n
Σexp(Ai)
i=1
C exp(Ak)
= ───────────
n
C Σexp(Ai)
i=1
exp(Ak + logeC)
= ───────────
n
Σexp(Ai + logeC)
i=1
-
例えば、
-
10の3乗は、10の1乗*10の2乗 = 1,000
-
10の4乗は、10の2乗*10の2乗 = 10,000
-
なので、下のような変形ができるということになる。
(a+b) a b X = X * X
-
-
X の b 乗 = C は、b = logxC であるから、下のようになる。
a a logxC (a+logxC) C X = X * X = X exp(Ak + C') = ─────────── n Σexp(Ai + C') i=1 -
Cは、入力信号中の最大値を使用する。
これによって、オーバーフローが発生し難くなる。以下に実装を示す。
"""This is a test program."""
import numpy as np
def softmax(aaa):
"""Softmax関数"""
exp_a = np.exp(aaa - np.max(aaa))
sum_exp_a = np.sum(exp_a)
return exp_a / sum_exp_a
# print(softmax(np.array([0.3, 2.9, 4.0])))
print(softmax(np.array([1010, 1000, 990])))出力層のニューロンの数は、問題に合わせて決定する。
- 分類問題 : 分類する数に合わせる。
- 回帰問題 : 多分、1つにする。
- 実践的な手書き数字画像の認識を行う。
- ここでは、学習済みのパラメタを使用して実装をする。
機械学習分野で最も有名なデータセット
-
手書き数字の画像セット
-
数字の0-9で構成され、以下の画像を使用して学習/推論を行う。
- 学習用の訓練画像 :60,000枚
- 推論用のテスト画像:10,000枚
-
-
28*28の単一チャンネル、グレー画像
- 画像の1つのピクセルは、0-255の8ビット
- 画像には、正解を意味するラベルが与えられている。
- 白黒画像は行列で表現でき、
カラー画像は テンソル(行列 * RGB)で表現できる。
-
以下にアクセスして[Download ZIP]する。
- oreilly-japan/deep-learning-from-scratch:
『ゼロから作る Deep Learning』のリポジトリ
https://github.com/oreilly-japan/deep-learning-from-scratch
- oreilly-japan/deep-learning-from-scratch:
-
Cドラ直下にZIP解凍したら、CMDでch03ディレクトリに移動する。
-
ここでpythonで
mnist_show.pyを実行し、
mnist.py経由で
データセットを取得する。
c:\deep-learning-from-scratch-master\ch03>python mnist_show.py
Downloading train-images-idx3-ubyte.gz ...
Done
Downloading train-labels-idx1-ubyte.gz ...
Done
Downloading t10k-images-idx3-ubyte.gz ...
Done
Downloading t10k-labels-idx1-ubyte.gz ...
Done
Converting train-images-idx3-ubyte.gz to NumPy Array ...
Done
Converting train-labels-idx1-ubyte.gz to NumPy Array ...
Done
Converting t10k-images-idx3-ubyte.gz to NumPy Array ...
Done
Converting t10k-labels-idx1-ubyte.gz to NumPy Array ...
Done
Creating pickle file ...
Done!
5
(784,)
(28, 28)
c:\deep-learning-from-scratch-master\ch03>python mnist_show.py
5
(784,)
(28, 28)
-
一回目はWebからのダウンロードは成功したが、画像表示ができなかった。
二回目以降は、ローカル保存した*.pklからデータを読み込むようで、画像表示できた。
なお、*.pklファイルは、pythonのbinaryserialize的なpickleによって生成されている。-
\dataset\mnist.pklは、MNISTデータ -
\ch03\sample_weight.pklは、重みパラメタ
-
-
入力層が784個、出力層が10個とする。
- 入力層が784個 = 28 * 28 のピクセル数
- 出力層が10個 = 分類問題なので、0 - 9 のクラス
-
中間層(隠れ層)の数は任意だが、ココでは以下の値に設定。
- 第一層:50個
- 第二層:100個
以下のように
neuralnet_mnist.pyを
実行すると、
>python neuralnet_mnist.py
- 推論用のテスト画像:10,000枚の分類結果の正解率が表示される。
- なお、ここでは、画像データに正規化(normalize)の前処理(preprocessing)を行っている。
バッチについてはニューラルネットワーク(学習)の該当節を参照。
- 上記の
neuralnet_mnist.py
処理中の重みパラメタを確認すると、
この、ニューラルネットワークが以下の様なものであることを確認できる。

- バッチ化は、X行列、Y行列の行を増やして
データを纏めて投入できるようにするだけで良い。
ソレに合わせてW行列も変わるがbに変更はない(1行n列)。

以下のように
neuralnet_mnist_batch.pyを
実行すると、
>python neuralnet_mnist_batch.py
- neuralnet_mnistと比べ、100枚づつのバッチ処理が行われ、高速化される。
- 正解の判定処理は、true値をsumするという方法を使用している。
- なお、np.argmaxの引数、axis=1は行方向の最大値となる要素のインデックスを求める。
移行メモ:本ページの図の元となる PowerPoint ファイルが添付されていたため、
DNET_NeuralNetworkInference_temp.pptxとして併置した。
Tags: 移行, 人工知能, 深層学習, ニューラルネットワーク, 推論, Softmax, MNIST, Python
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。