行列計算で全結合層の計算が実装できる?#
スカラー同士の計算から徐々に行列を使った実装に直していくので,それぞれのコードを見比べて,最終的なコードのお気持ちを理解してください.
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display, Markdown
ハイパーパラメータを定義しておきましょう.
M = 2 # batch_size
F = 3 # n_features
K = 4 # n_hidden_layer_units
C = 5 # n_classes
パラメータも初期化しておきます.全て標準正規分布に従う事にします.(初期化の方法は適当です)
X = np.random.random([M,F])
W0 = np.random.random([F,K])
b0 = np.random.random([K,])
ニューラルネットワークの全結合層をPythonプログラムで書いた例を以下に示します.
①,スカラーの四則演算だけで実装する場合#
# ①
output = np.zeros([M,K]) #答えの初期化
for m in range(M):
for k in range(K):
xh = np.zeros(F)
for f in range(F):
xh[f] = X[m,f] * W0[f,k]
output[m,k] = xh.sum() + b0[k]
output
array([[0.74817163, 0.83682236, 2.01578713, 0.67566289],
[1.20714837, 1.3665895 , 2.20171706, 0.93252512]])
②,①から入力層のニューロンを回すfor文を消して,ベクトル同士の内積で置き換えた場合”#
# ②
output = np.zeros([M,K]) #答えの初期化
for m in range(M):
for k in range(K):
xh = X[m] @ W0[:,k] # (F)@(F,1)->(,)
output[m,k] = xh + b0[k]
output
array([[0.74817163, 0.83682236, 2.01578713, 0.67566289],
[1.20714837, 1.3665895 , 2.20171706, 0.93252512]])
③,②から隠れ層のニューロンを回すfor文を消して,データベクトルと重み行列の内積で置き換えた場合#
# ③
output = np.zeros([M,K]) #答えの初期化
for m in range(M):
xh = X[m] @ W0 # (F)@(F,K)->(K)
output[m] = xh + b0 # (K)+(K)->(K)
output
array([[0.74817163, 0.83682236, 2.01578713, 0.67566289],
[1.20714837, 1.3665895 , 2.20171706, 0.93252512]])
④,③からミニバッチを回すfor文を消して,ミニバッチ行列と重み行列の内積で置き換えた場合#
output = X @ W0 + b0
output
array([[0.74817163, 0.83682236, 2.01578713, 0.67566289],
[1.20714837, 1.3665895 , 2.20171706, 0.93252512]])