本レポートはラビットチャレンジの深層学習day1のレポートである
深層学習(ディープラーニング)とは、人間の神経細胞の仕組みを再現したニューラルネットワークを用いた機械学習の手法の1つ。多層構造のニューラルネットワークを用いることが特徴としてあげられる。
入力層と出力層の間に中間層を設け、中間層を多層化して学習する。層を増やすことで、情報の複雑さに対応できるようになる。
ニューラルネットワーク
Q. ディープラーニングは結局何をやろうとしているのか?
A. 入力層・出力層に加えて多数の中間層を用いることによって、従来の機械学習モデルより複雑な識別・予測を可能にし、AIの活用範囲を大幅に拡大しようとしている。
Q. 次の中のどの値の最適化が最終目的か?
①入力値、②出力地、③重み、④バイアス、⑤総入力、⑥中間層入力、⑦学習率
A. ③, ④
ニューラルネットワークに最初に数値を入力する層のこと。input layerとも言う。
図1の$x_1$$x_2$$x_3$$x_4$が入力層に当たる。
入力層から情報を受け継ぎ、さまざまな計算を行う層のこと。中間層が多いほど複雑な分析ができる。
図1の$v_1$$v_2$$v_3$$v_4$が中間層に当たる。
入力層を$x= (x_1,x_2,…,x_n)^{\mathrm{T}}$
重みを$W = (w_1,w_2,…,w_n)^{\mathrm{T}}$
バイアスを$b$とすると、
中間層$u = Wx+b$
Q.$u=x_1w_1+x_2w_2+x_3w_3+x_4w_4+b$ をpythonで表せ
A.
u = np.dot(x,w)+b
Q.「1_1_forward_propagation.ipynb」の中間層の出力を定義している箇所を抜き出せ。
A.
# 中間層出力
z = functions.relu(u)
ニューラルネットワーク中の1つのニューロンにおいて,複数ノードの和を入力として,その出力を最終決定する関数のこと。
代表的な活性化関数には、「ステップ関数」、「シグモイド関数」、「ReLu関数」、「ソフトマックス関数」、「恒等関数」がある。中間層ではシグモイド関数は過去に頻繁に使われていたが、勾配消失問題が生じるため、ReLu関数が主流となっていった。
# ステップ関数
def step_function(x):
return np.where( x > 0, 1, 0)
# シグモイド関数
def sigmoid(x):
return 1/(1 + np.exp(-x))
# ReLU関数
def relu(x):
return np.maximum(0, x)
# ソフトマックス関数
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))
Q.線形と非線形の違いを図に書いて簡易に説明せよ
A.
線形と非線形の違い
線形な関数は
・加法性: $f(x+y) = f(x)+f(y)$
・斉次性: $f(kx) = kf(x)$
を満たす。
非線形な関数は加法性・斉次性を満たさない。
Q. ソースコードより該当する箇所($z=f(u)$)を抜き出せ
z = functions.sigmoid(u)
ニューラルネットワークに最後に結果を出力する層のこと。output layerとも言う。
図1の$y_1$$y_2$$y_3$が出力層に当たる。
出値力と正解値の誤差による関数のこと。損失関数ともいう。
代表的なものに「平均二乗誤差」、「平均絶対誤差」、「平均二乗対数誤差」、「交差エントロピー誤差」がある。
誤差関数を減少させることで精度を向上させる。
平均二乗誤差$MSE = \frac{1}{n}\sum_{i=1}^n(y_i - \hat{y}_i)^2$
#平均二乗誤差
def mean_squared_error(d, y):
return np.mean(np.square(d - y)) / 2
Q. 何故引き算ではなく2乗するか述べよ
A. 引き算では、各誤差の符号を統一することができないため、誤差を打ち消しあってしまう可能性があるから。
Q. 下式の1/2はどういう意味を持つか述べよ。
image.png
A. 1/2があることで微分の計算が容易にできるという計算上の意味を持つ。しかし、本質的な意味はない。
Q. ①~③の数式に該当するソースコードを示し、1行ずつ処理の説明をせよ
image.png
A.
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))
①return np.exp(x) / np.sum(np.exp(x))
→ ソフトマックス関数の定義の処理をしている
②np.exp(x)
→ 自然対数の底eのx乗を表している
③np.sum(np.exp(x))
→ ②の総計を表している
Q. ①~③の数式に該当するソースコードを示し、1行ずつ処理の説明をせよ
image.png
A.
def cross_entropy_error(d, y):
if y.ndim == 1: # ミニバッチの考慮
d = d.reshape(1, d.size)
y = y.reshape(1, y.size)
# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
if d.size == y.size:
d = d.argmax(axis=1)
batch_size = y.shape[0]
# 1e-7を足す理由はlog(0)のとき、-∞に発散するのは防止するため
return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size
①def cross_entropy_error(d, y):
→ 交差エントロピー誤差の定義を表している
② return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size
→ 予測した確率の対数と真の確率の積の総和を表している
学習の誤差を最小にするためにパラメータを繰り返し操作して最適なパラメータを算出する手法。
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]
# 誤差
loss = functions.mean_squared_error(d, y)
losses.append(loss)
勾配降下法には大きく3つの種類がある
①バッチ勾配降下法(最急降下法)
②確率的勾配降下法(SGD)
③ミニバッチ勾配降下法
バッチ勾配降下法では、全データを使って関数の最小値を探索する。
・全てのデータを使うので、結果が安定する
・解への到達が早いことが多い
・計算量が多くなる
・メモリの消費量が多い
・局所解にハマりやすい
S確率的勾配降下法では、ランダムに抽出した1つのデータを使って関数の最小値を探索する。
・メモリの使用量が少ない
・オンライン学習が可能
・外れ値の影響を受けやすい
ミニバッチ勾配降下法は、SGDとバッチ勾配降下法の間をとった方法。データの一部を利用して、関数の最小値を探索する。
バッチ勾配降下法と確率的勾配降下法のハイブリッドであるので、それぞれの良い点と悪い点の両方を持っており、バランスの良い手法と言える。
Q. 該当するソースコードを探しなさい
image.png
A.
network[key] -= learning_rate * grad[key]
Q. オンライン学習とは何か
A. 1つのデータが入ってくるたびにパラメーターを更新する学習方法。
メモリの使用量は少ないが、外れ値の影響を受けやすい。
誤差逆伝播法とは、関数の偏微分を効率的に計算する手法のこと。算出された誤差を、出力層側から順に微分し、前の層へと伝播していく。
ニューラルネットワークの学習を効率よくするために利用される。
誤差逆伝播法
「入力層の数 > 出力層」の時、計算量が少なくなる。
def backward(self, dout):
dx = np.dot(dout, self.W.T)
self.dW = np.dot(self.x.T, dout)
self.db = np.sum(dout, axis = 0)
return dx
Q. 誤差逆伝播法では、不要な再帰的処理を避けることができる。
既に行った計算結果を保持しているソースコードを抽出せよ
A.
# 出力層でのデルタ
delta2 = functions.d_mean_squared_error(d, y)
# b2の勾配
grad['b2'] = np.sum(delta2, axis=0)
# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)
# 中間層でのデルタ
delta1 = np.dot(delta2, W2.T) * functions.d_sigmoid(z1)
delta1 = delta1[np.newaxis, :]
# b1の勾配
grad['b1'] = np.sum(delta1, axis=0)
x = x[np.newaxis, :]
# W1の勾配
grad['W1'] = np.dot(x.T, delta1)
Q. 2つの空欄に該当するソースコードを探せ
image.png
A.
delta1 = np.dot(delta2, W2.T) * functions.d_sigmoid(z1)
grad['W1'] = np.dot(x.T, delta1)
ゼロから作るDeep Learning, 斎藤 康毅, オライリー・ジャパン
統計学実践ガイドブック, 日本統計学会
キカガクブログ ニューラルネットワークの数学(逆伝播)
https://free.kikagaku.ai/tutorial/basic_of_deep_learning/learn/neural_network_basic_backward
AI研究所 -損失関数・誤差関数
https://ai-kenkyujo.com/term/loss-function-error-function/
交差エントロピー誤差をわかりやすく説明してみる
https://qiita.com/kenta1984/items/59a9ef1788e6934fd962