[メモ]ゼロから作るDeep Learning 3章・4章

· ·

ゼロから作る Deep Learning ―Python で学ぶディープラーニングの理論と実装」は以前途中まで読んでいたけれども復習もかねて。

※ここでは MNIST の手書き数字の判定が例となっています

3 章 ニューラルネットワーク 🔗

  • ニューラルネットワークは適切な重みパラメータをデータから自動で学習できる -入力層、中間層(隠れ層)、出力層
  • 式を書き換え

$$y = h(w_1x_1 + w_2x_2 + b)$$ $$h(x) = \begin{cases} 0 & (x \leq 0 )\\ 1 & ( x > 0 )\end{cases}$$

  • $h(x)$ は活性化関数(activation function)
  • 活性化関数が、パーセプトロンからニューラルネットワークへ進むための架け橋になる
  • 閾値を定めてそれを堺に出力が切り替わる関数は「ステップ関数」「階段関数」と呼ばれ、パーセプトロンは「ステップ関数」を採用している
  • ステップ関数を他の関数へ変更することでニューラルネットワークへと進む
  • シグモイド関数(sigmoid function) $$h(x) = \frac{1}{1+exp(-x)}$$
  • ステップ関数実装
1
2
3
def step_function(x):
    y = x > 0 # bool値に変換
    return y.astype(np.int) # 0,1の数値に変換
  • 更に簡易に
1
2
def step_function(x):
    return np.array(x > 0, dtype = np.int)
  • シグモイド関数実装
1
2
def sigmoid(x):
    return 1 / (1 + np.exp(-x))
  • シグモイド関数の滑らかさがニューラルネットワークの学習において重要な意味を持つ
  • ニューラルネットワークでは活性化関数に非線形関数を用いる。逆に線形関数は用いてはならない。多層にするメリットが失われるため
  • ReLU(Rectified Linear Unit) 関数 $$h(x) = \begin{cases} x & (x > 0)\\0 & (x \leq 0)\end{cases}$$
1
2
def relu(x):
    return np.maximum(0, x)
  • 行列のドット積は np.dot を利用する

出力層 🔗

  • 恒等関数 : 入ってきたものに対して何も手を加えずに出力する関数
  • ソフトマックス関数

$$y_k = \frac{exp(a_k)}{\sum^{n}_{i=1}exp(a_i)}$$

  • 出力層 n 個
  • k 番目の出力 $y_k$
  • 入力信号 $a_k$
  • 以下の python コードは数式を単純にプログラム化したのみだが極端に大きな数字を扱うのみなどは不都合が生じる欠陥がある
1
2
3
4
5
def softmax(a):
    exp_a = np.exp(a)
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    return y
  • 改善
1
2
3
4
5
6
def softmax(a):
    c = np.max(a)
    exp_a = np.exp(a - c) # オーバーフロー対策
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    return y

4 章 ニューラルネットワークの学習 🔗

  • 特徴量 : 入力データから本質的なデータを的確に抽出できるように設計された変換器
  • 訓練データ(教師データ)とテストデータに分けて汎化能力を正しく評価する
  • 過学習(overfitting) : あるデータセットだけに過度に適応した状態
  • 損失関数 : ニューラルネットワークの性能の"悪さ"を示す指標
    • 2 乗誤差
    • エントロピー誤差
  • 2 乗誤差

$$E = \frac{1}{2}\sum_k(y_k - t_k)^2$$

  • $y_k$ : ニューラルネットワークの出力
  • $t_k$ : 教師データ
  • $k$ : データの次元数
  • one-hot 表現 : 正解ラベルを 1 として、それ以外は 0 で表す表記法
  • 最終的にニューラルネットワークで出力されたデータ y に対して正解データ(教師データ)t の各要素の差の 2 乗を計算し、その総和を求める
1
2
def mean_squared_error(y, t):
    return 0.5 * np.sum((y - t) ** 2)
  • 交差エントロピー誤差

$$E = - \sum_{k}t_klog_{y_k}$$

  • $y_k$ : ニューラルネットワークの出力
  • $t_k$ : 正解ラベル(one-hot 表現)
1
2
3
def cross_entropy_error(y, t):
    delta = 1e-7
    return -np.sum(t * np.log(y + delta)) # np.log(0)のマイナス無限大を防ぐための微小値加算
  • 訓練データを使って学習するとは、正確に言うと、訓練データに対する損失関数を求め、その値をできるだけ小さくするようなパラメータを探し出す、ということ
  • 訓練データすべての損失関数の和を求めたい場合の交差エントロピー誤差

$$E = -\frac{1}{N}\sum_{n}\sum_{k}t_{nk}log_{y_{nk}}$$

  • $N$ : データ数
  • $t_{nk}$ : n 個目のデータの k 番目の値、教師データ
  • $y_{nk}$ : ニューラルネットワークの出力
  • すべてのデータを対象にして損失関数の和を求めるには時間がかかる場合があるため、データの中から一部を選び出し、その一部のデータを全体の「近似」として利用する「ミニバッチ」ごとに学習する(ミニバッチ学習)
  • ミニバッチのようなバッチデータに対応した交差エントロピー誤差
1
2
3
4
5
6
7
def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)

    batch_size = y.shape[0]
    return -np.sum(t * np.log(y + 1e-7)) / batch_size
  • y : ニューラルネットワークの出力
  • t : 教師データ
  • y の次元数が 1 の場合(データひとつあたりの交差エントロピー誤差を求める場合)は、データの形状を整形
  • 教師データが one-hot 表現ではなく、実際の正解データラベルとして与えられた場合
1
2
3
4
5
6
7
def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)

    batch_size = y.shape[0]
    return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size
  • 偏微分 : 複数の変数からなる関数の微分
  • 勾配(gradient) : すべての変数と偏微分をベクトルとしてまとめたもの
  • 勾配法 : 勾配をうまく利用して関数の最小値(または、できるだけ小さな値)を探す方法
  • 勾配法の数式(1 回あたりの更新式)

$$x_0 = x_0 - \eta\frac{\partial{f}}{\partial{x_0}}$$ $$x_1 = x_1 - \eta\frac{\partial{f}}{\partial{x_1}}$$

  • $\eta$ : 更新の量。学習率(learning rate)。一回の学習で、どれだけ学習すべきか、どれだけパラメータを更新するかを決める。
  • ハイパーパラメータ : 学習率のような人の手によって設定されるパラメータ
  • ニューラルネットワークの学習 4 ステップ
    1. ミニバッチ
    2. 勾配の算出
    3. パラメータの更新
    4. 繰り返す
  • 確率的勾配降下法(stochastic gradient descent) : 使用するデータを見にバッチとして無作為に選ばれたものを利用するもの。(無作為に選びだしたデータに対して行う勾配降下法)
  • エポック : 1 エポックとは学習に置いて訓練データをすべて使いきったときの回数
comments powered by Disqus