0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rabbit Challenge レポート(深層学習 DAY1)

Last updated at Posted at 2020-12-24

1. 入力層~中間層

入力: $x_i$

重み: $w_i$

バイアス: $b$

総入力: $u = w_1x_1 + w_2x_2 + ... w_nx_n + b = Wx + b$

活性化関数: $f$

2. 活性化関数

活性化関数: $ f^{(l)}(u^{(l)}) = [f^{(l)}(u_1^{(l)}...u_j^{(l)})]$

中間層で用いられる活性化関数

ステップ関数

def step_function(x):
  if x > 0:
    return 1
  else:
    return 0

0~1の間を表現できず、線形分離可能なものしか学習しなかった

シグモイド関数

def sigmoid(x):
  return 1/1(+np.exp(-x))

ステップ関数では表現できない0~1の値を表すことができ、NN普及のひっかけとなった

大きな値では出力の変化が微弱なため、勾配消失問題を引き起こすことがあった

RELU関数

def relu(x):
  return np.maximum(0,x)

昨今最も使われている活性化関数

勾配消失問題の回避とスパース化に貢献することで良い結果をもたらしてくれる

3. 出力層

誤差関数

平均二乗誤差

$En(w) = \frac{1}{2}\sum_{j=1}^l(y_j-d_j)^2 = \frac{1}{2}||(y-d)||^2$

# 平均二乗誤差
def mean_squared_error(d, y):
    return np.mean(np.square(d - y)) / 2

交差エントロピー

$ En(w) = \ \sum_{i=1}^l d_i\log y_i$

# クロスエントロピー
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]
    return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size

活性化関数

出力層と中間層との違い

  • 値の強弱

    • 中間層:閾値の前後で信号の強弱を調整
    • 出力層: 信号の大きさ(比率)はそのままに変換
  • 確率出力

    • 分類問題の場合は出力層の出力は0~1の範囲に限定し、総和を1にする

ソフトマックス関数

使い分け

image.png

# ソフトマックス関数
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))

4. 勾配降下法

勾配降下法

$w^{(t+1)} = w^{(t)} - \epsilon \nabla E$

$\nabla E=\frac{\partial E}{\partial w} = [ \frac{ \partial E}{ \partial w_1}...\frac{ \partial E}{ \partial w_M}]$

学習率

学習が小さい場合発散することは無いが、小さすぎると収束するまでに時間がかかる

以下のようなアルゴリズムがある

  • Momentum
  • AdaGrda
  • Adadelta
  • Adam ←よく利用される

確率的勾配降下法

ランダムに抽出したサンプルの誤差を求める

$w^{(t+1)} = w^{(t)} - \epsilon \nabla E_n$

メリット

  • データが冗長な場合の計算コストの削減
  • 望まない局所極小解に収束するリスク削減
  • オンライン学習ができる

ミニバッチ勾配降下法

オンライン学習の考えを取り入れ、分割してバッチ学習を行う

$w^{(t+1)} = w^{(t)} - \epsilon \nabla E_n$

$E_t = \frac{1}{N_t} \sum_{n \in D_t}^{} E_n$

$N_t = |D_t|$

ランダムに分割したデータの集合(ミニバッチ) Dtに属するサンプルの平均誤差を求める

メリット

  • 確率的勾配降下法のメリットを損なわず、計算機の計算資源を有効活用できる
  • 並列での学習が可能

誤差勾配の計算

どう計算する?

$ \nabla E = \frac{\partial E}{\partial w} = [ \frac{\partial E}{\partial w_1} ... \frac{\partial E}{\partial w_M}]$

数値微分

プログラムで微小な数値を生成し、疑似的に微分を計算する一般的な手法

$\frac{\partial E }{\partial w_m} \approx \frac{E(w_m+h)-E(w_m -h)}{2h}$

5. 誤差逆伝播法

誤差逆伝播法

算出された誤差を、出力層側から順に微分し、前の層前の層へと伝播。最小限の計算で各パラメータの微分値を解析的に計算する手法

誤差関数: $ E(y) = \frac{1}{2} \sum_{j=1}^l(y_j-d_j)^2 = \frac{1}{2}||y-d||^2$

出力層の活性化関数: $y=u^{(t)}$

総入力の計算: $u^{(t)} = w^{(l)}z^{(l-1)}+b^{(l)}$

$\frac{\partial E}{\partial w_{ji}^{(2)}} = \frac{\partial E}{\partial y} \frac{\partial y}{\partial u} \frac{\partial u}{\partial w_{ji}^{(2)}} = (y_j-d_j)z_j$

$\frac{\partial E(y)}{\partial y} = \frac{\partial}{\partial y} \frac{1}{2} || y -d ||^2 = y-d $

$ \frac{\partial y(u)}{\partial u} = \frac{\partial u}{\partial u} = 1$

# 誤差逆伝播
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)
    # b2の勾配
    grad['b2'] = np.sum(delta2, axis=0)
    # W2の勾配
    grad['W2'] = np.dot(z1.T, delta2)
    # 中間層でのデルタ
    #delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1)

    ## 試してみよう
    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)
  
    # print_vec("偏微分_重み1", grad["W1"])
    # print_vec("偏微分_重み2", grad["W2"])
    # print_vec("偏微分_バイアス1", grad["b1"])
    # print_vec("偏微分_バイアス2", grad["b2"])

    return grad

確認テスト

確認テスト1-1

Q. ディープラーニングはなにをしようとしているか。

A. プログラムの代わりにニューラルネットワークを利用し、入力値から目的値を求めるモデルを作成する

補足: 重み[w]やバイアス[b]を求める

確認テスト1-2

Q. 次のネットワークを紙にかけ

入力層: 2ノード1層

中間層: 3ノード2層

出力層: 1ノード1層

A.

image.png

確認テスト1-3

Q. この図式に動物分類の実例を入れてみよう

image.png

A.
x1: 体の大きさ

x2: 体の長さ

x3: 耳の大きさ

x4:しっぽの大きさ

確認テスト1-4

Q. この数式をPythonで書け

$ u = w_1x_1+w_2x_2+w_3x_3 = b$

A. u = np.dot(x, W) + b

確認テスト1-5

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

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

補足: 中間層が今回は1つ

確認テスト2-1

Q.線形と非線形の違いを図にかいて簡易に説明せよ

image.png

左図 線形: 直線で表せることができるもの

右図 非線形: 表せないもの

[補足]

線形な関数は以下を満たす

  • 加法性: f(x+y) = f(x) + f(y)
  • 斉次性: f(kx) = kf(x)

確認テスト2-2

Q.
$z = f(u) ... (1.5)$

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

# 1層の総出力
z1 = functions.relu(u1)

[補足]
from common import functionsという形でimportされているので関数自体は別ファイルに定義されている

def relu(x):
return np.maximum(0, x)

確認テスト3-1

$ En(w) = \frac{1}{2}\sum_{j=1}^l(y_j-d_j)^2 = \frac{1}{2}||(y-d)||^2$

Q.なぜ引き算ではなく二乗するのか

A.必ず正の値になるように調整するため

Q.1/2はどういう意味をもつのか

A.誤差逆伝搬の計算で微分を行う際に計算が簡単になる

補足:1/2に本質的な意味はない

確認テスト3-2

ソフトマックス関数の①~③に該当するソースコードを示し、説明せよ

image.png

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)③) ・・・①

9行目 return の箇所が実際の数式に該当する箇所である

補足: 3行目からの分岐はミニバッチで利用する処理

その他の処理はプログラムを安定させるための記述

確認テスト3-3

image.png

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

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]
    return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7))(②) / batch_size ・・・①

A. 11行目 returnの文が該当

補足: 1e-7は対数関数を∞に飛ばした時、0になってしまうことを防ぐために利用している

確認テスト4-1

Q.オンライン学習とは何か

A.データをリアルタイムで読み取り、パラメータを更新する方法

補足: バッチ学習は一度にすべての学習データを使ってパラメータ更新を行う

確認テスト4-2

Q.この数式の意味を図に書いて説明せよ

$ w^ {(t+1)} = w^ {(t)} - \epsilon \nabla E_n$

A.
〇 -> 〇 -> 〇
t -> t+1 -> t+2
重みが $-\epsilon \nabla En $ずつ加えられていくイメージ

[参考]
image.png

確認テスト5-1

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

A.

# 出力層でのデルタ
delta2 = functions.d_mean_squared_error(d, y)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?