More Related Content
Similar to 深層学習 Day1レポート (20)
深層学習 Day1レポート
- 4. (1)—2入力層~中間層実装演習
import numpy as np
from common import functions
def print_vec(text, vec):
print("*** " + text + " ***")
print(vec)
print("shape: " + str(vec.shape))
print("")
#順伝播(単層・単ユニット)
W = np.array([[0.1], [0.2]])
print_vec("重み", W)
b = np.array(0.5)
print_vec("バイアス", b)
x = np.array([2, 3])
print_vec("入力", x)
u = np.dot(x, W) + b
print_vec("総入力", u)
z = functions.relu(u)
print_vec("中間層出力", z)
*** 重み ***
[[0.1]
[0.2]]
shape: (2, 1)
*** バイアス ***
0.5
shape: ()
*** 入力 ***
- 5. [2 3]
shape: (2,)
*** 総入力 ***
[1.3]
shape: (1,)
*** 中間層出力 ***
[1.3]
shape: (1,)
#順伝播(単層・複数ユニット)
W = np.array([
[0.1, 0.2, 0.3,0],
[0.2, 0.3, 0.4, 0.5],
[0.3, 0.4, 0.5, 1],
])
print_vec("重み", W)
b = np.array([0.1, 0.2, 0.3])
print_vec("バイアス", b)
x = np.array([1.0, 5.0, 2.0, -1.0])
print_vec("入力", x)
u = np.dot(W, x) + b
print_vec("総入力", u)
z = functions.sigmoid(u)
print_vec("中間層出力", z)
*** 重み ***
[[0.1 0.2 0.3 0. ]
[0.2 0.3 0.4 0.5]
[0.3 0.4 0.5 1. ]]
shape: (3, 4)
*** バイアス ***
- 6. [0.1 0.2 0.3]
shape: (3,)
*** 入力 ***
[ 1. 5. 2. -1.]
shape: (4,)
*** 総入力 ***
[1.8 2.2 2.6]
shape: (3,)
*** 中間層出力 ***
[0.85814894 0.90024951 0.93086158]
shape: (3,)
#順伝播(3 層・複数ユニット)
def init_network():
print("##### ネットワークの初期化 #####")
network = {}
input_layer_size = 3
hidden_layer_size_1=10
hidden_layer_size_2=5
output_layer_size = 4
network['W1'] = np.random.rand(input_layer_size, hidden_layer_size_1)
network['W2'] = np.random.rand(hidden_layer_size_1,hidden_layer_size_2)
network['W3'] = np.random.rand(hidden_layer_size_2,output_layer_size)
network['b1'] = np.random.rand(hidden_layer_size_1)
network['b2'] = np.random.rand(hidden_layer_size_2)
network['b3'] = np.random.rand(output_layer_size)
print_vec("重み 1", network['W1'] )
print_vec("重み 2", network['W2'] )
print_vec("重み 3", network['W3'] )
print_vec("バイアス 1", network['b1'] )
print_vec("バイアス 2", network['b2'] )
- 7. print_vec("バイアス 3", network['b3'] )
return network
def forward(network, x):
print("##### 順伝播開始 #####")
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
u1 = np.dot(x, W1) + b1
z1 = functions.relu(u1)
u2 = np.dot(z1, W2) + b2
z2 = functions.relu(u2)
u3 = np.dot(z2, W3) + b3
y = u3
print_vec("総入力 1", u1)
print_vec("中間層出力 1", z1)
print_vec("中間層出力 2", z2)
print_vec("総入力 2", u2)
print_vec("出力", y)
print("出力合計: " + str(np.sum(y)))
return y, z1, z2
x = np.array([1., 2., 4.])
print_vec("入力", x)
network = init_network()
y, z1, z2 = forward(network, x)
- 8. *** 入力 ***
[1. 2. 4.]
shape: (3,)
##### ネットワークの初期化 #####
*** 重み 1 ***
[[0.37778847 0.24658434 0.74491222 0.03213593 0.32038564 0.58835526
0.86365818 0.58949594 0.1124516 0.62755882]
[0.76953067 0.37140577 0.06084915 0.43549414 0.8215288 0.33404207
0.07474437 0.67119999 0.31453689 0.45849188]
[0.36685051 0.1966258 0.23653951 0.59110512 0.99408675 0.40792207
0.72483135 0.85130317 0.27997765 0.9621285 ]]
shape: (3, 10)
*** 重み 2 ***
[[0.85837715 0.83942546 0.79882007 0.1639335 0.15983972]
[0.67601382 0.18415901 0.6062716 0.60128177 0.42585243]
[0.48165607 0.77838427 0.9834378 0.69202874 0.27045343]
[0.23311313 0.19791733 0.95230552 0.09457593 0.58263762]
[0.03567006 0.12421143 0.3912111 0.77900302 0.50673893]
[0.87581596 0.80896226 0.20178657 0.62744589 0.49621901]
[0.39515304 0.09923986 0.27496628 0.31316822 0.083332 ]
[0.64254764 0.63058664 0.88462971 0.73731741 0.68169922]
[0.12222021 0.86301851 0.39931212 0.85525334 0.30930921]
[0.67271314 0.00537922 0.00531959 0.04597142 0.83515054]]
shape: (10, 5)
*** 重み 3 ***
[[0.37509197 0.27953494 0.92096775 0.72398534]
[0.62594863 0.85461602 0.48468366 0.88008667]
[0.39212505 0.31799436 0.23299625 0.82013324]
[0.73739036 0.28078926 0.6052556 0.76846287]
[0.55855366 0.3958231 0.5507254 0.72587945]]
shape: (5, 4)
*** バイアス 1 ***
[0.31627945 0.0903909 0.53150955 0.15726896 0.16240443 0.22404565
0.91840582 0.0791023 0.65747361 0.62573279]
- 9. shape: (10,)
*** バイアス 2 ***
[0.57760747 0.68935605 0.98367619 0.29844546 0.2177973 ]
shape: (5,)
*** バイアス 3 ***
[0.23729621 0.51597681 0.64517804 0.33129204]
shape: (4,)
##### 順伝播開始 #####
*** 総入力 1 ***
[3.70053128 1.86628999 2.34427812 3.42481365 6.10219469 3.11217332
4.83087815 5.41621089 2.51890957 6.01878939]
shape: (10,)
*** 中間層出力 1 ***
[3.70053128 1.86628999 2.34427812 3.42481365 6.10219469 3.11217332
4.83087815 5.41621089 2.51890957 6.01878939]
shape: (10,)
*** 中間層出力 2 ***
[19.63244842 16.01859044 20.81089341 18.61715608 18.77054645]
shape: (5,)
*** 総入力 2 ***
[19.63244842 16.01859044 20.81089341 18.61715608 18.77054645]
shape: (5,)
*** 出力 ***
[50.00102611 38.96873619 52.94439379 73.64209727]
shape: (4,)
出力合計: 215.55625336655427
- 12. 回帰 二値分類 多クラス分類
活性化関数 恒等写像
𝑓(𝑢) = 𝑢
シグモイド関数
𝑓(𝑥) =
1
1 + 𝑒−ℎ𝑥
ソフトマックス関数
𝑓(𝑖, 𝑢) =
𝑒𝑢𝑖
∑ 𝑒𝑢𝑘
𝐾
𝑘=1
(𝐾はクラス数)
誤差関数 二乗誤差
1
2
∑(𝑦𝑖 − 𝑑𝑖 )2
𝑙
𝑖=1
交差エントロピー
− ∑ 𝑑𝑖 × log𝑦𝑖
𝑙
𝑖=1
交差エントロピーの例:バナナ、リンゴ、みかんに分類し、写真がバナナの場合(1, 0, 0)
→推定した分布が(0.8, 0.1, 0.1)である場合、交差エントロピー誤差は、
−(1 × log0.8 + 0 × log0.1 + 0 × log0.1) = −log0.8 = −(−0.09) = 0.09
→推定した分布が(0.3, 0.4, 0.3)である場合、交差エントロピー誤差は、
−(1 × log0.3 + 0 × log0.4 + 0 × log0.3) = −log0.3 = −(−0.52) = 0.52
(3)—1【確認テスト】
〇なぜ、引き算ではなく二乗するか述べよ。
===
引き算を行うだけでは、各ラベルでの誤差で正負両方の値が発生し、全体の誤差を正しくあらわすのに
都合が悪い。二乗してそれぞれのラベルでの誤差を正の値になるようにする。
===
〇下式の 1/2 はどういう意味を持つか述べよ。
===
実際にネットワークを学習するときに行う誤差逆伝播の計算で、誤差関数の微分を用いるが、その際の
計算式を簡単にするため。本質的な意味はない。
===
〇①~③の数式に該当するソースコードを示し、一行ずつ処理の説明をせよ。
(ソフトマックス関数)
===
①def softmax(x): 関数の定義
②np.exp(x) 入力値に対するエクスポネンシャル
③np.sum(np.exp(x)) 上記を足し合わせたもの
===
- 13. 〇①、②の数式に該当するソースコードを示し、一行ずつ処理の説明をせよ。
(交差エントロピー)
===
①def cross_entropy_error(d, y): 関数の定義
②-np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size:
y の log の値と d を掛けたものを足し合わせ、その総和にマイナスをつけたもの
===
(3)—2出力層実装演習
#ソフトマックス関数
def softmax(x):
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x)
return np.exp(x) / np.sum(np.exp(x))
#平均二乗誤差
def mean_squared_error(d, y):
return np.mean(np.square(d - y)) / 2
#クロスエントロピー
def cross_entropy_error(d, y):
if y.ndim == 1:
d = d.reshape(1, d.size)
y = y.reshape(1, y.size)
if d.size == y.size:
d = d.argmax(axis=1)
batch_size = y.shape[0]
return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size
- 16. (4)—2勾配降下法実装演習
#確率勾配降下法(全体の実装は(5)誤差逆伝播法で実装している)
data_sets_size = 100000
data_sets = [0 for i in range(data_sets_size)]
for i in range(data_sets_size):
data_sets[i] = {}
data_sets[i]['x'] = np.random.rand(2)
data_sets[i]['d'] = f(data_sets[i]['x'])
losses = []
learning_rate = 0.07
epoch = 1000
network = init_network()
random_datasets = np.random.choice(data_sets, epoch)
for dataset in random_datasets:
x, d = dataset['x'], dataset['d']
z1, y = forward(network, x)
grad = backward(x, d, z1, y)
for key in ('W1', 'W2', 'b1', 'b2'):
network[key] -= learning_rate * grad[key]
(5)誤差逆伝播法
誤差逆伝播法とは、算出された誤差を、出力層側から順に微分し、目の層へと伝播する手法である。こ
れより、最低限の計算で各パラメータでの微分値を解析的に計算する。計算結果(=誤差)から微分を逆
算することで、不要な再帰的計算を避けて微分を算出することができ、効率よく各パラメータの更新量
を計算できる。
- 18. (5)—2誤差逆伝播法実装演習
#確率勾配降下法
import numpy as np
from common import functions
import matplotlib.pyplot as plt
def print_vec(text, vec):
print("*** " + text + " ***")
print(vec)
#print("shape: " + str(x.shape))
print("")
def f(x):
y = 3 * x[0] + 2 * x[1]
return y
def init_network():
network = {}
nodesNum = 10
network['W1'] = np.random.randn(2, nodesNum)
network['W2'] = np.random.randn(nodesNum)
network['b1'] = np.random.randn(nodesNum)
network['b2'] = np.random.randn()
return network
def forward(network, x):
W1, W2 = network['W1'], network['W2']
b1, b2 = network['b1'], network['b2']
u1 = np.dot(x, W1) + b1
z1 = functions.relu(u1)
u2 = np.dot(z1, W2) + b2
y = u2
return z1, y
- 19. def backward(x, d, z1, y):
grad = {}
W1, W2 = network['W1'], network['W2']
b1, b2 = network['b1'], network['b2']
delta2 = functions.d_mean_squared_error(d, y)
grad['b2'] = np.sum(delta2, axis=0)
grad['W2'] = np.dot(z1.T, delta2)
delta1 = np.dot(delta2, W2.T) * functions.d_sigmoid(z1)
delta1 = delta1[np.newaxis, :]
grad['b1'] = np.sum(delta1, axis=0)
x = x[np.newaxis, :]
grad['W1'] = np.dot(x.T, delta1)
return grad
data_sets_size = 100000
data_sets = [0 for i in range(data_sets_size)]
for i in range(data_sets_size):
data_sets[i] = {}
data_sets[i]['x'] = np.random.rand(2)
data_sets[i]['d'] = f(data_sets[i]['x'])
losses = []
learning_rate = 0.07
epoch = 1000
network = init_network()
random_datasets = np.random.choice(data_sets, epoch)
for dataset in random_datasets:
x, d = dataset['x'], dataset['d']
z1, y = forward(network, x)
grad = backward(x, d, z1, y)
for key in ('W1', 'W2', 'b1', 'b2'):
- 20. network[key] -= learning_rate * grad[key]
loss = functions.mean_squared_error(d, y)
losses.append(loss)
print("##### 結果表示 #####")
lists = range(epoch)
plt.plot(lists, losses, '.')
plt.show()