深層学習: Day1

動画講義の要約

Section1: 入力層~中間層

  • 入力層とは、一番最初に値が入力される層の事である。そこに重み(入力層の値をどれくらいの割合で使うかの設定値)を作用させて、中間層へ出力させる
  • 重みは W_{ij} は、入力 i と 中間層ユニット j に関して値が決定されていて、数式で表示させると、以下のようになる。 (入力層が4つの場合)

ω _ {1}x _ {1}ω _ {2}x _ {2}ω _ {3}x _ {3}ω _ {4}x _ {4} + b = WX + b

Section2: 活性化関数

ニューラルネットワークおいて、次の層への出力を決定する非線形の関数。 入力値によって、次の層への信号のON/OFF や強弱を定める働きを持つ。

中間層用の活性化関数と出力層用の活性化関数がある。

  • 中間層用の活性化関数

    • シグモイド関数(初期によく使われてた。0 ~ 1 の値をとる。大きな値では微分値が小さく、勾配消失問題の原因となりやすい。)
    • ReLu関数(最も使われる。勾配消失問題が回避される。)
    • ステップ関数(現在ではあまり使わない)
  • 出力層用の活性化関数

    • シグモイド関数(2値分類に使用。出力層の値を確率に変換する。)
    • ソフトマックス関数(多クラス分類に使用。出力層の値を確率に変換する。)
    • 恒等写像( 回帰問題に使用。入力値をそのまま出力する。)

Section3: 出力層

【誤差関数】

ニューラルネットワークが導き出した答えと、実際のデータ(訓練データ)の答えが合ってるか間違っているかを確認する必要がある。 つまり、どれくらい合っているか間違っているかを確認する必要がある。その尺度に使われるのが誤差関数である。

yは正解ラベル dはニューラルネットワークが導いた出力値(yとd逆にしても、2乗和誤差は変わらない、と思う。)

  • 2乗和誤差(回帰問題に使われる) :  \frac{1}{2}\displaystyle\sum_{i=1}^{l} (yi−di)^{2}
  • クロスエントロピー(分類問題に使われる) :  -\displaystyle\sum_{i=1}^{l}d{i} log y{i}

Section4: 勾配降下法

学習とは

誤差関数が最小になるように、最適な重みやバイアスを見つける事である。そのための手法が勾配降下法である。

学習率とは

誤差関数を最小になるように学習を繰り返す事中で、前回の学習から得られた誤差をどれだけ次の学習に生かすかを決定するパラメータ(下記のε)

W^{(t+1)} = W^{(t)}  - ε \nabla E
 \nabla E = \dfrac{\partial E}{\partial w}

勾配降下法の学習率の決定、収束性向上のアルゴリズムは以下のようなものがある。 * Momentum
* AdaGrad
* Adadelta
* Adam(よく使用されるらしい)

エポック

学習はエポックという単位で繰り返される。1エポックとは、例えば10000枚の訓練データ、100個のミニバッチだと、学習を100回行うと全ての訓練データを見た事になる。この場合1エポック = 100回となる。

勾配降下法には、バッチ勾配降下法, 確率的勾配降下法,ミニバッチ勾配降下法がある。

バッチ勾配降下法

  • 一回のパラメータ更新に全部の訓練データすべてを利用ため、メモリ上にすべてデータが乗らない場合がある。

確率的勾配降下法

  • 全サンプルからランダムに一つのデータ選んで、そこから誤差関数を求め、学習させていく方法。
  • メリットとして、オンライン学習ができる。データが冗長な場合の計算コストの削減ができる。

ミニバッチ勾配降下法

  • バッチ勾配降下法と確率的勾配降下法の中間を取った方法。𝑁 個の訓練データの中から𝑛個を取り出し、パラメータの更新をする。
  • 並列処理(SIMD)が出来るので計算が早い。

 - ε \nabla Eの求め方

数値微分  \dfrac{\partial E}{\partial w_m} = \dfrac{E(w_m + h)E(w_m - h)}{2h}
の方法があるが、これだと計算量が多く、無駄が多い。→誤差逆伝搬法を用いる。

Section5: 誤差逆伝播

  • 誤差(関数)をパラメータで微分した関数を利用し、出力層側から、ネットワークのパラメータ更新を行う。
  • 数値微分のように計算量が多くならない。最小限の計算で、解析的にパラメータの更新量を計算する事ができる。
  • 誤差(関数)の重みでの微分値は、微分の連鎖率を利用し、上の層の微分値(出力層側から入力層に向けて)を再起的に利用しながら求められていく。

    確認テスト

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

明示的なプログラムの代わりに、多数の中間層を持つニューラルネットワークを用いて、入力値から目的とする出力値に変換する数学モデルを構築する事。

重みとバイアスの最適化が最終目的である。つまり3、4

(考察)重みとバイアスの最適化により、最適な出力値が算出される。

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

入力層:2ノード1層
中間層:3ノード2層
出力層:1ノード1層
f:id:foino74:20201209130307j:plain

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

f:id:foino74:20201209131057j:plain

【P22】この数式をPythonで書け。
numpyを使って内積を計算する
ω _ {1}x _ {1}ω _ {2}x _ {2}ω _ {3}x _ {3}ω _ {4}x _ {4} + b = WX + b

import numpy as np
u1 = np.dot(X,W) + b

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

1_1_forward_propagation.ipynbの、順伝播(3層・複数ユニット)から抜き出す。 中間層は2つある。 reluは次のsectionで出てくる活性化関数

# 中間第1層の総入力
u1 = np.dot(x, W1) + b1

# 中間第1層の総出力
z1 = functions.relu(u1)
    
# 中間第2層の総入力
u2 = np.dot(z1, W2) + b2
    
# 中間第2層の総出力
z2 = functions.relu(u2)

Section2: 活性化関数

【P27】線形と非線形の違いを図にかいて簡易に説明せよ。 f:id:foino74:20201213001338j:plain

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

1_1_forward_propagation.ipynbの、順伝播(単層・複数ユニット)から抜き出す。

活性化関数を使用している箇所は、

z = functions.sigmoid(u)

【P45】

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

(ans) 引き算を行うだけでは、各ラベルでの誤差で正負両方の値が発生し、全体の誤差を正しく表すのに都合が悪い。2乗する事で各ラベルの誤差を必ず正の値にする。1/2は便宜上の問題。実際にネットワークを学習する時に行う誤差逆伝搬法で、誤差関数の微分をするが、その際の計算を簡単にするため。本質的な意味はない。

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

# ソフトマックス関数
def softmax(x):
    ・・・・本質的な計算は以下の戻り値のみ 
    return np.exp(x) / np.sum(np.exp(x))

①def softmax(x) ソフトマックス関数の値 ②np.exp(x) 分子.出力層の値xの指数関数 ③np.sum(np.exp(x)) 分母.各出力層の値xの指数関数の和ととっている

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

# クロスエントロピー
def cross_entropy_error(d, y):
   ・・・・本質的な計算は以下
    return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7))

①def cross_entropy_error(d, y) dは正解ラベル(one-hot表現だと0 or 1), yはニューラルネットワークからの出力 ②return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7))

batch_sizeはバッチサイズであり、戻り値は交差エントロピーの値(one_hot表現であってもそうでなくても、対応する事ができる) また1e-7 をプラスしているのは、np.log(0)のような計算が発生した場合、-∞になってしまい、この先の交差エントロピー計算が出来なくなる。 そうならないようにするために微小な値を加算している。

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

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

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

学習データが入ってくるたびに都度パラメータを更新し、学習を進めていく方法。 一方バッチ学習では、一度の全ての学習データを使ってパラメータ更新を行う。

【P69】この数式の意味を図に書いて説明せよ。
エポックごとに、重みを更新し(更新量は誤差関数の勾配と学習率をかけたもの)最適な重みを計算していく。

f:id:foino74:20201213223315j:plain

【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_mean_squared_error(d, y)
  ## (1)↑ここで 誤差関数の導関数(誤差関数dを出力値yで微分したもの)の値を求めている。

    # 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_sigmoid(z1)
    ## (4)↑ここでも (1) の値 (delta2) を利用している。
    delta1 = delta1[np.newaxis, :]

    # b1の勾配
    grad['b1'] = np.sum(delta1, axis=0)
   ## (5)↑ここで (4) の値 (delta1) を利用している。

    x = x[np.newaxis, :]
    # W1の勾配
    grad['W1'] = np.dot(x.T, delta1)
     ## (6)↑ここでも (4) の値 (delta1) を利用している。
    
    return grad

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

1_3_stochastic_gradient_descent.ipynbのdef backward(x, d, z1, y):より抜き出す。

 \dfrac{\partial E}{\partial y}\dfrac{\partial y}{\partial u} → delta2 = functions.d_mean_squared_error(d, y) 恒等写像なのでdelta2と変わらない。
 \dfrac{\partial E}{\partial y}\dfrac{\partial y}{\partial u}\dfrac{\partial u}{\partial ω^{(2)}_{ji}} → grad['W2'] = np.dot(z1.T, delta2)