ラビット☆チャレンジ 提出レポート

深層学習: Day1

動画講義の要約

Section1: 入力層~中間層

  • 入力層のそれぞれの入力に関して、重みが掛け合わされて加算された値が第一の中間層のユニットに入力される。
  • 重みは $w_{ij}$ は、入力 $i$ と 中間層ユニット $j$ に関してそれぞれ値が決定されている。(ネットワークのパラメータ)

Section2: 活性化関数

  • NN において、次の層への出力を決定する非線形の関数。
    • 非線形であることは NN にとって本質的に重要。
  • ON/OFF を次の層に強めに渡すのか、弱めに渡すのか、ということで、そこで人間らしさ的なものを出している。
  • 例1: シグモイド関数 $ \frac{1}{1 + e ^ {-x}} $
    • 0 ~ 1 の値をとる。
    • 絶対値が大きくなると、勾配が小さくなってしまう。→ 勾配消失問題
    • ゼロにならない。 → スパース化できない。計算量が無駄に発生してしまう。
  • ReLU
    • $0 (x < 0), 1 (0 <= x)$
    • 現世代では第一の選択肢となる関数 (必ずしも最適というわけではない)
    • プラスで」あれば勾配はゼロにはならない。
    • 0 をとることでスパース化のメリットがある。

Section3: 出力層

誤差関数

  • 二乗和誤差 $ \frac{1}{2}\sum(y_{i}-d_{i})^2$
  • 分類問題に関してはクロスエントロピー関数を利用するのが普通。

出力層の活性化関数

  • 中間層と出力数で活性化関数を利用する目的が異なるので、同一である必要はない。
  • 回帰問題の場合: 恒等関数 $y=x$ / 誤差関数は二乗誤差
  • ロジスティック回帰: シグモイド関数 $y = \frac{1}{1+\exp^{-x}}$ / 誤差関数は交差エントロピー
  • 分類問題: ソフトマックス関数 $y(i,u) = \frac{e^{u_i}}{\sum_{k=1}^{K}e^{u_k}}$ / 誤差関数は交差エントロピー

Section4: 勾配降下法

  • 勾配降下法
    • 一回のパラメータ更新に訓練データすべてを利用する。
    • 計算量 (空間・時間) が訓練データ n に対して $O(n)$ 必要となる。
  • 確率的勾配降下法(SGD)
    • サンプルのうち 1 つのデータごとにパラメータの更新を行う。
    • 学習結果はサンプルのデータ順に依存する。
    • 計算量と収束速度の面でメリットがある。
  • ミニバッチ勾配降下法
    • 狭義の確率的勾配降下法では、GPU等のSIMDのメリット等を生かせないため、ある程度の数のサンプルをまとめて1回のパラメータ更新に利用する。
    • 文脈によっては、SGD(確率的勾配降下法) に含める場合もある。
  • 訓練データ1周を「エポック」としてカウントする。

Section5: 誤差逆伝播法

  • 誤差(関数)をパラメータで微分した関数を利用し、出力層側から、ネットワークのパラメータ更新を行う。
  • 最小限の計算で、(数値微分ではなく) 解析的にパラメータの更新量を計算する手法。
  • 逆伝播をすることで、不要な再帰的計算(探索)を避けるという意味もある。

確認テストの考察

In [4]:
import numpy as np

P11】ディープラーニングは、結局何をやろうとしているか2行以内で述べよ。 また、次の中のどの値の最適化が最終目的か。 全て選べ。

①入力値[ X] ②出力値[ Y] ③重み[W]④バイアス[b] ⑤総入力[u] ⑥中間層入力[ z] ⑦学習率[ρ]

■ 考察

最終目的は②出力値の最適化と思われるが、入力データとして訓練データや検証データが与えられた場合だけではなく、 未知の入力に対しても出力値が最適化されていることが必要と考えられる。(汎化性能)

P13】次のネットワークを紙にかけ。

  • 入力層:2ノード1層
  • 中間層:3ノード2層
  • 出力層:1ノード1層

■ 考察

紙に書いたネットワーク図

P20】この図式に動物分類の実例を入れてみよう。

■ 考察

動物の例を入れる

P22】この数式をPythonで書け。

■ 考察

In [5]:
def compute_u(W, x, b):
    return W @ x.T + b # ← 該当の数式の Python 実装

# 以下確認用コード
W = np.array([1,2,3,4])
x = np.array([4,3,2,1])
b = 10

print (compute_u(W,x,b))
30

P24】1-1のファイルから 中間層の出力を定義しているソースを抜き出せ。

■ 考察

# 中間層出力
z = functions.relu(u)
print_vec("中間層出力", z)

P27】線形と非線形の違いを図にかいて簡易に説明せよ。

■ 考察

$y=f(x)$ において $ \frac{\Delta{y}}{\Delta{x}} $ が定数 (xの値によらず一定) の場合に、

$f(x)$ は線形関数というのではないか。(それ以外は非線形関数)

紙に書いた線形非線形の違い

P34】配布されたソースコードより該当する箇所を抜き出せ。

■ 考察

z1 = functions.sigmoid(u)

P45

  • なぜ、引き算でなく二乗するか述べよ
  • 下式の1/2はどういう意味を持つか述べよ

■ 考察

  • 絶対値をとる演算 (abs) であると、解析的に微分が不能となってしまう。
  • 微分する目的は、元の関数の極小値を求める (導関数が0となる点を求める) ことである。この目的に対して 1/2 を掛ける影響はない。また、微分をした際に「降りてくる」2とこの 1/2 が打ち消しあい 1 となり、計算が簡略化されるため。

P52】①~③の数式に該当するソースコードを示し、一行づつ処理の説明をせよ。

■ 考察

def softmax(x):

$i$ は引数としてとらず、すべての $f(u)$をリストとして返す関数である。

np.exp(x)

NumPy の exp 関数を利用している。(関数定義と同様、すべての x に関して個別に計算を行う形である。)

np.exp(x), axis=0

$u$ のすべての要素のに関して、$\exp$を底として指数の合計をとっている。

P54】①~②の数式に該当するソースコードを示し、一行づつ処理の説明をせよ。

■ 考察

def cross_entropy_error(d, y):
  • 引数dは、教師データのエントロピー ( one-hot-vector 形式でも可 ) である。

return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7))
  • $y, d$ は正規化 (合計が1となっていること) されていることが前提である。
  • 1e-7 をプラスしているのは、log 演算に引数 0 を渡すことを防ぐため。
    • この関数では、$y$ はゼロ以上であることが前提である。(負であってはならない。)

P57】該当するソースコードを探してみよう。

 network[key]  -= learning_rate * grad[key]

P66】オンライン学習とは何か2行でまとめよ

■ 考察

ユーザーの操作等、リアルタイムで取得されるデータに対して、

そのデータを用いて誤差逆伝播法(確率的勾配降下法)を行い、随時ネットワークのパラメータを更新していくこと。

P69】この数式の意味を図に書いて説明せよ。

■ 考察

$t+1$ 時点でのパラメータ $W$ は、$t$ 時点でのパラメータ $W$ から、$t$ 時点での誤差 $E$ の傾き (勾配) に比例した量 (比例係数: 学習係数 $\epsilon$) を引いたものである。

紙に書いた線形非線形の違い

P79】誤差逆伝播法では不要な再帰的処理を避ける事が出来る。 既に行った計算結果を保持しているソースコードを抽出せよ。

■ 考察

# 誤差逆伝播
def backward(x, d, z1, y):
    print("\n##### 誤差逆伝播開始 #####")

    grad = {}

    W1, W2 = network['W1'], network['W2']
    b1, b2 = network['b1'], network['b2']
    #  出力層でのデルタ
    delta2 = functions.d_sigmoid_with_loss(d, y)
    ## (1)↑ここで シグモイド関数とクロスエントロピーの合成関数の導関数の値を求めている。

    #  b2の勾配
    grad['b2'] = np.sum(delta2, axis=0)
    ## (2)↑ここで (1) の値 (delta2) を利用している。

    #  W2の勾配
    grad['W2'] = np.dot(z1.T, delta2)
    ## (3)↑ここでも (1) の値 (delta2) を利用している。

    #  中間層でのデルタ
    delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1)  
    ## (4)↑ここでも (1) の値 (delta2) を利用している。

P84】2つの空欄に該当するソースコードを探せ

■ 考察

① $ \frac{\partial E}{\partial y} \frac{\partial y}{\partial u}$

    # b2の勾配
    grad['b2'] = np.sum(delta2, axis=0)

② $ \frac{\partial E}{\partial y} \frac{\partial y}{\partial u} \frac{\partial u}{\partial w^{(2)}_{ji}}$

    # W2の勾配
    grad['W2'] = np.dot(z1.T, delta2)

演習結果と考察

DN06_Jupyter演習

演習実施結果

考察

  • np.array の初期化方法に関しては、リテラルで記述する方法以外にも各種の方法があることが分かった。
  • ネットワークの形を変化させることの具体的なイメージがついた。
  • 講義通り、誤差関数として、多クラス分類ではクロスエントロピー誤差、回帰では二乗和誤差を利用していたが、二値分類に関しては講義と異なり二乗和誤差関数の定義となっていた。状況に応じ柔軟な誤差関数の利用をしてもよいということかと思った。

DN15_Jupyter演習2

演習実施結果

考察

  • 実装上、順伝播の際の活性化関数の変更 (例: sigmoid → relu) と、誤差逆伝播における導関数の変更がセットであることを改めて認識した。
  • 訓練データは単純な線形なものであったが、訓練データにおける x の範囲を変更しただけでも、モデルの収束に大きな影響が発生することを実感できた。
In [ ]: