深層学習DAY1



####ニューラルネットワークの全体像

例えば入力に体長X1=10、体重X2=300、ひげの本数X3=300、といったような入力データがあり、中間層で重みWをかけて,バイアスbを加えて変換すると出力Yが犬の確率Y1＝0.1、猫の確率Y2=0.05といったような確率を得る。


- 確認テスト

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

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

- 確認テスト

Q：次のネットワークを紙にかけ。
入力層：２ノード１階
中間層：３ノード２階
出力層：１ノード１階

A：
-![深層学習DAY1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653571/2d3b2961-699f-935d-26f4-90d432ffa9b0.png)

####ニューラルネットワーク（NN）できること

【回帰分析】
線形回帰
回帰木
ランダムフォレスト
ニューラルネットワーク(NN)

【分類分析】
ベイズ分類
ロジスティック回帰
決定木
ランダムフォレスト
ニューラルネットワーク（NN）

- 実用例
自動売買（トレード）
チャットボット
翻訳
音声解釈
囲碁、将棋AI

### Section1 入力層～中間層
- 確認テスト

Q：この図式に動物分類の実例を入れる。

A：例X1:体長、X2：足の長さ、X3：耳の大きさ、X4：髭の本数、X5：平均の髭の長さ

- 確認テスト

Q：この数式をpythonで書け。
$$ u=w_1x_1+w_2x_2+w_3x_3+w_4x_4+b=Wx+b$$

A: u = np.dot(x, W1) + b1

- 確認テスト

Q：中間層の出力を定義しているソースを抜き出せ。

A: u2 = np.dot(z1, W2) +b2
   Z2 = functions.relu(u2)

### Section2 活性化関数
- 確認テスト

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

A:線形な関数は加法性、斉次性を満たす。非線形な関数は加法性・斉次性を満たさない。

![深層学習DAY1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653571/0778c40c-038e-3749-606d-f301c6ca301c.png)

中間層用の活性化関数
- Relu関数
- シグモイド（ロジスティック）関数
- ステップ関数

出力層用の活性化関数
- ソフトマックス関数
- 恒等関数
- シグモイド（ロジスティック）関数

ステップ関数
閾値を超えたら発火する関数であり、出力は常に1か０。パーセプトロン（ニューラルネットワークの前身）でりようされた関数。

シグモイド関数
0~1の間を緩やかに変化する関数で、ステップ関数ではON/OFFしかない状態に対し、信号の強弱を伝えられるようになり、予想ニューラルネットワーク普及のきっかけとなった。

Relu関数
今最も使われている関数
勾配消失問題の回避とスパース化に貢献することで良い成果をもたらしている。

- 確認テスト

Q：配布されたソースコードより該当する箇所を抜き出せ。
A: Z1 = functions.relu(u1)

### Section3 出力層

#####全結合NN-誤差関数
入力データからNNにデータを渡し、出力としてでた値と訓練データを比べる。出力された値と訓練データとの差が誤差であり、表現として誤差関数を用いる。

- 確認テスト

Q：なぜ、引き算ではなく２乗するか述べよ。1/2はどうゆう意味をもつのか述べよ。
$$ E_n(w) = \frac{1}{2}\sum_{j=1}^l(y_j-d_j)^2 =\frac{1}{2}\begin{Vmatrix}(y-d)\end{Vmatrix}^2
$$

A:
２乗する理由
引き算を行うだけでは、各ラベルでの誤差で正負両方の値が発生し、全体の誤差を正しく表すのに都合が悪い。２乗してそれぞれのラベルで誤差を正の値になるようにする。
1/2する理由
実際にネットワークを学習するときに行う誤差逆伝播の計算で、誤差関数の微分を用いるが、その際の計算式を簡単にするため、本質的な意味はない。

#####全結合NN-出力層の活性化関数
情報を抽出するための中間層と、抽出された情報を使いやすいように加工する出力層で役割が異なる。
分類問題の場合、出力層の出力は0~1の範囲に限定し、総和を１とする必要がある。

出力層の種類として回帰では恒等関数、二値分類ではシグモイド関数、他クラス分類はソフトマックス関数を用いる。
- 確認テスト

Q：ソフトマックス関数
$$ f(i,u) = \frac{e^{u_i}}{\sum_{k=1}^{k}e^{u_k}}$$
数式に該当するコードを示し、処理の説明をせよ。

```
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))
```

A: ２行目から５行目まではミニバッチとしてデータを取り扱うときに使用する。本質的な関数は最後の１文。

- 確認テスト

Q：交差エントロピー
$$ E_n(w) = -\sum_{i=1}^{l}{d_i}logy_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
```
A:２行目から５行目までは使い勝手をよくするためにデータを取り扱うときに使用する。本質的な関数は最後の１文。1e-7というのは対数関数では0のときに-∞になってしまうため、ごくわずかな小さな値を足すことにより、ゼロに落ちないようにするため。

#####全結合NN-勾配降下法
深層学習の目的は学習を通じて誤差を最小にするネットワークを作成すること→勾配降下法を利用してパラメータを最適化

- 確認テスト

Q:$$w^{(t+1)}=w^t-ε\nabla{E}$$
該当するソースコードを探してみよう。

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

#####確率的勾配降下法（SGD)
確率的勾配降下法のメリット
- データが冗長な場合の計算コストの削減
- 望まない局所極小解に収束するリスクの軽減
- オンライン学習ができる

- 確認テスト

Q:オンライン学習とは何か？

A:オンライン学習とは学習データが入って来る度に都度パラメータを更新し、学習を進めていく方法。バッチ学習との違いを把握しておく。

- 確認テスト

Q:$$w^{(t+1)}=w^t-ε\nabla{E_t}$$
この数式の意味を図に書いて説明せよ。

A:
![3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653571/20e13915-a639-53ad-d175-2f08f632834b.jpeg)

#####誤差逆伝搬法の計算
- 確認テスト

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

A:
delta2 = functions.d_mean_squarred_error(d, y)
delta1 = np.dot(delta2, W2.T) * functions.d_sigmoid(z1)

誤差逆伝搬法は微分の連鎖律を用いると、簡易に計算できる。

- 確認テスト

Q:
$$ \frac{\partial {E}}{\partial y}\frac{\partial y}{\partial u}
$$
$$ \frac{\partial {E}}{\partial y}\frac{\partial y}{\partial u}
\frac{\partial u}{\partial w_ji^{(2)}}
$$
に該当するソースコードを探せ。

A：delta2 = functions.d_mean_squarred_error(d, y)
delta1 = np.dot(delta2, W2.T) * functions.d_sigmoid(z1)
grad['W1'} = np.dot(x.T, delta1)