ディープラーニング辞書

# 概要
ディープラーニングに関する言葉をよく忘れるので、自分用に辞書のようなものを作成しました。

# 基礎・構成要素
### ノード / ニューロン / ユニット
値が渡されたら、処理をして次に渡す機能をもつ部品。

### レイヤー / 層
同じ階層のノードをまとめたもの。

### 重み / パラメータ
伝播されたデータに対してかける係数。

### バイアス
前のレイヤーから伝播された値とは別に存在する、各ユニットへのインプットデータ。

### 学習率 / 学習係数
1回の重み更新（学習）で、どのくらい更新するかの度合い。

### 局所解 / 局所的最適解
近傍では最適な解と判断される点。広域で見たときに決して最適解とはなるわけではない。

<img width="400" alt="Screenshot 2018-03-13 12.14.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/06c9e9ff-65ae-a596-45cc-f6233fd456b6.png">


### 鞍点
あるパラメータの勾配は上がるが、別の勾配は下がる点。

<img width="350" alt="Screenshot 2018-03-13 12.17.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/d8336ba7-66bb-8181-6ec2-e53a1cf17852.png">


### 順伝播法 / フォワードプロパゲーション
入力層から、インプットデータを順々に伝播させてネットワークを通して出力層まで演算結果を出力する方法。

### 誤差逆伝播法 / バックプロパゲーション
合成関数の微分連鎖律によって、損失関数の偏微分結果と各ユニットに対するインプットデータを利用し、出力層から入力層に向かって微分結果を逆伝播させることで、各パラメータの勾配を求める方法。


[Qiita 誤差逆伝播法のノート：誤差逆伝播法のまとめ](https://qiita.com/Ugo-Nama/items/04814a13c9ea84978a4c#%E8%AA%A4%E5%B7%AE%E9%80%86%E4%BC%9D%E6%92%AD%E6%B3%95%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81)

### バッチ正規化 (Batch Normalization)
各レイヤーのインプットを分散が一定になるように変換すること。
勾配消失・爆発を防いだり、過学習を防ぐ効果がある。

各インプットを以下のように変換。

```math
\hat{x^{(k)}} = \frac{x^{(k)}-E[x^{(k)}]}{\sqrt{Var[x^{(k)}] + \varepsilon}}
```

（hatが変な位置になる...）

### 早期終了 /  早期打ち切り (Early Stopping)
過学習をしないように、途中で学習を打ち切ること。
学習用・テスト用データとは別に過学習の検証用データを持っておき、学習毎に学習用データと検証用データの評価誤差を監視。誤差が広がってしまったら学習をストップする。


### 正則化
過学習を抑えるためのテクニック。

#### L1正則化

正則化項 $\lambda R(\mathbf{w})$ を損失関数に加える。

```math
R(\mathbf{w})=\sum_{i=1}|w_i|
```

特定のパラメータが0に近づくように、学習が進む。インプットにあきらかな不要なものがある場合に有効。

<img width="300" alt="Screenshot 2018-03-13 12.38.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/f72850e7-7a8e-7c1a-06ea-d58b7bce6362.png">


#### L2正則化

正則化項 $\lambda R(\mathbf{w})$ を損失関数に加える。

```math
R(\mathbf{w})=\sum_{i=1}w_i^2
```

$w_i$それぞれが小さくなるように、学習が進む。汎用性を高めたいときに利用。

<img width="300" alt="Screenshot 2018-03-13 12.38.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/b848ece4-85e2-13fb-6a9f-55fc1c66fd98.png">


### ドロップアウト
いくつかのノードをランダムに不活性化させて学習することで、過学習を防ぐテクニック。

## 活性関数（activation function）
### 恒等関数（liner / identity）
入力をそのまま出力する。
回帰の出力層で使われる。

```math
f(x)=x
```

<img width="300" alt="liner.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/0992905b-30f3-f507-4aa0-0cc8930d5960.png">

### ステップ関数（step）
最適化のための勾配に基づくアプローチが出来ないため、今はほとんど使われない。

```math
f(x) =\left\{
\begin{array}{ll}
1 \quad (x \geq 0) \\
0 \quad (x \lt 0) 
\end{array}
\right.
```

<img width="400" alt="step.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/b6d42513-567e-9001-dde2-df21ab728858.png">


### シグモイド関数 / ロジスティック関数（sigmoid / logistic sigmoid ）
0~1を滑らかにとる関数で、微分が容易。
ただし、勾配消失があり、スパース性はなし。

```math
f(x) = \frac{1}{1+e^{-x}}
```

<img width="400" alt="sigmoid.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/7777e315-b491-6025-03e2-e7dff5a33127.png">


### ReLU（ランプ関数）
0以上の場合に恒等関数となる。
最も良く利用されている活性関数。
スパース性があり、入力が0以上で微分が常に1になるため計算スピードも速い。

```math
f(x) =\left\{
\begin{array}{ll}
x  \quad  (x \geq 0) \\
0  \quad (x \lt 0) 
\end{array}
\right.
```

<img width="400" alt="relu.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/8083a262-d0ae-bfa2-d2ce-34e0430fc197.png">


### Thanh（ハイパボリックタンジェント）
Sigmoidを下に引き伸ばした感じ。
同じく、勾配消失があり、スパース性はなし。

```math
f(x) = \frac{2}{1+e^{-2x}}-1
```

<img width="400" alt="htan.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/eff41f28-85cd-0750-5c13-03460b3aca53.png">

### ソフトプラス（softpuls）
ReLUを滑らかにした形。
初期化においてロバストになるはたらきがある。

```math
f(x) = \ln(1+e^x)
```

<img width="400" alt="softplus.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/3a2a135f-1306-663c-4e09-813b828f5d29.png">


### elu
ReLUの派生で、出力の平均を0に近くする。

```math
f(x) =\left\{
\begin{array}{ll}
x  \quad  (x \geq 0) \\
\alpha(e^x-1)  \quad (x \lt 0) 
\end{array}
\right.
```

<img width="400" alt="elu.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/15c1669d-7489-6978-6ce0-5018db9f931f.png">
$\alpha=0.7$

### ソフトマックス（softmax）
出力層で使う活性関数で、基本的に分類で使われる。
他のものと違い、同一レイヤーすべての値を使用して算出され、同一レイヤーの出力合算が1になる。


```math
f(x_i) = \frac{exp(x_i)}{\sum_{k} exp(x_k)}
```

### 勾配消失(vanishing gradient)・勾配爆発
バックプロパゲーションにて、微分結果を逆伝播していくうちに0に収束してしまい、上位レイヤーで勾配が消失してしまうことを、勾配消失。逆を勾配爆発という。
重みの更新が適切にされずに学習がうまくいかなくなる。

## 損失関数 loss / 誤差関数 error / コスト関数 cost / 目的関数 objective 
名前の違い [Qiita : 目的関数、コスト関数、誤差関数、損失関数いろいろあるけど、なにが違うのかを検討](https://qiita.com/kakiuchis/items/5cfe52e6f75dd75f96e7)

### 二乗誤差(MSE : mean squared error)
回帰で利用される。正規分布を仮定した際の最尤推定。

```math
L(x) = \frac{(t-y(x))^2}{2}
```
### クロスエントロピー誤差
分類で使用される損失関数。
正解$t$の確率分布から得られるエンコード方法で予測の確率分布をエンコードしたときの差を表す。そのため、出力がsoftmax関数などで正規化する必要がある。

```math
L(x) = -\sum_{k}t_k\log y_k(x)
```

[クッキーさんの日記](http://cookie-box.hatenablog.com/entry/2017/05/07/121607)

### ヒンジ損失
SVMで使われる損失関数。
同じく出力がsoftmaxなどで正規化されている必要がある。


```math
L(x) = \sum_{k}max(0, 1-t_k y_k(x))
```

### ε-許容損失
SVMの回帰で使われる損失関数

```math
L(x) = max(0, |1-t y(x)| - \varepsilon)
```

## 勾配降下法
### 最急降下法（バッチ勾配降下法 / バッチ学習）
全データの誤差の合計を使って勾配を計算し、重みを更新する方法。データ量が多いと大変。

二乗誤差の誤差合計

```math
L(w)=\frac{1}{2}\sum_{n=1}^{N}( t_n -y(x_n;w) )^2
```

クロスエントロピー誤差の誤差合計

```math
L(w) = -\sum_{n=1}^N \sum_{k=1}^K t_{nk}\log y_k(x_n;w)
```

### 確率的勾配降下法(SGD)
データ1つずつランダムに取り出して1つのデータの誤差を使って、勾配を計算して重みを更新する方法。最急降下法より、局所解に陥りにくい。
$\eta$は学習率で0.01とか。

```math
\mathbf{w}^{t + 1} \gets \mathbf{w}^{t} - \eta \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}
```

### ミニバッチ勾配降下法 / Mini-Batch SGD
データを複数個セット（ミニバッチ）でランダムに取り出して、重みを更新する方法。

<img width="250" alt="Screenshot 2018-03-13 13.37.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/b317c1bb-beeb-de82-1845-d211a3836c36.png">


### エポック(epoch)
学習回数の数え方で、学習データを使った回数。パラメータを何回更新したとしても、学習データを使い切って1エポックとカウントする。

### イテレーション数
重みを更新する回数。学習の回数。

## 最適化
良く学習が進むように重みの更新の仕方を工夫

### モメンタム法（慣性）
前回の更新と同じ方向なら加速させて、逆なら減速させるように調整したもの。$\alpha$は減衰率で0.9とか。

```math
\mathbf{v}^{t + 1} = \alpha \mathbf{v}^{t} - \eta \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}} \\

\mathbf{w}^{t + 1} = \mathbf{w}^{t} -\mathbf{v}^{t + 1} 

```

<img width="270" alt="Screenshot 2018-03-13 14.39.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/eee54745-9a70-0566-f13c-49571c5a3669.png">


### NAG（Nesterov accelerated gradient）
モメンタム法の変形版で、勾配計算でも前回の更新差を考慮に入れることで、向きが変わったときに、一歩前で減速できる。

```math
\mathbf{v}^{t + 1} =  \alpha (\mathbf{v}^{t}) - \eta \frac{\partial L(\mathbf{w}^{t}＋ \alpha (\mathbf{v}^{t}))}{\partial \mathbf{w}^{t}}
\\
\mathbf{w}^{t + 1} = \mathbf{w}^{t} -\mathbf{v}^{t + 1}\\

```


<img width="300" alt="Screenshot 2018-03-13 14.39.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/6947d43d-baf2-9a90-8d7a-f42a2af83693.png">

### AdaGrad
個々のパラメータに対して個別の学習率で更新できる。そして、学習率を恣意的に決めずに自動で調整してくれる方法。ただし、学習が進むと、$h_t$は累積増加していき、学習率が減少してパラメータがちょっとしか更新されなくなる。
$\varepsilon$は$10^{-8}$、$h_0$は$0$、$\alpha$は$0.001$など。

```math
h_t = h_{t-1} + \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}^2　\\
　\\
\mathbf{w}^{t + 1} = \mathbf{w}^{t} - \frac{\alpha}{ \sqrt{h_t}+\varepsilon} \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}

```

### RMSprop
AdaGradeを改良したもの。過去の勾配の影響で$h_t$が大きくなる問題を、抑え目になるように調整したもの。
$\gamma$は$0.9$など。

```math
h_t = \gamma h_{t-1} + (1-\gamma) \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}^2　\\
　\\
\mathbf{w}^{t + 1} = \mathbf{w}^{t} - \frac{\alpha}{ \sqrt{h_t}+\varepsilon}  \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}

```

### AdaDelta
RMSpropをさらに改良したもの。初期学習パラメータ$\alpha$を取り除いた。
$\gamma = 0.95$, $\varepsilon = 10^{-6}$ぐらい。

```math
h_t = \gamma h_{t-1} + (1-\gamma) \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}^2\\
　\\
v_t = \frac{\sqrt{s_t + \varepsilon}}{\sqrt{h_t + \varepsilon}}\frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}\\
　\\
s_{t+1} = \gamma s_t + (s- \gamma)v_t^2\\
　\\
\mathbf{w}^{t + 1} = \mathbf{w}^{t} - v_t
```

### Adam
モメンタム法とRMSpropを組み合わせた方法。$m_t$は積率で推定した平均、$v_t$は分散。学習のはじめのほうでの初期値（$m_0=0$,　$v_0=0$）の影響を抑えるため、$\hat{m}, \hat{v}$としている。


```math
m_{t+1} = \gamma_1 m_t + (1- \gamma_1) \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}　\\
v_{t+1} = \gamma_2 m_t + (1- \gamma_2 ) \frac{\partial L(\mathbf{w}^{t})}{\partial \mathbf{w}^{t}}^2　\\
\hat{m} = \frac{m_{t+1}}{1- \gamma_1^t}\\
\hat{v} = \frac{v_{t+1}}{1- \gamma_2^t}\\
　\\
\mathbf{w}^{t + 1} = \mathbf{w}^{t} - \alpha \frac{\hat{m}}{\sqrt{\hat{v}} + \varepsilon}
```

### イメージ
<img width="350" alt="opt2.gif" src="https://qiita-image-store.s3.amazonaws.com/0/105335/985fb3a5-4913-56a8-c243-1ddb68ff817f.gif">


<img width="350" alt="opt1.gif" src="https://qiita-image-store.s3.amazonaws.com/0/105335/55bfd796-f5fd-b966-f87d-1eec93d0bd2e.gif">

Images credit: [Alec Radford](https://twitter.com/alecrad).

## レイヤー・結合の種類
### 全結合層 / Dense / Full connected layer/ Affine layer
隣接するすべてのユニットを結合する方法。

### 畳み込み層 / Convolution layer
フィルターと呼ばれる正方データを対象データ上をスライドさせて、重なる部分のデータとフィルターの積和を計算する。


### プーリング層 / Pooling layer
データを圧縮する。

#### Max pooling
対象領域の最大値を残して集約する手法

#### Average pooling
対象領域の平均で集約する手法

#### アップサンプリング(UpSampling) / アンプーリング
Poolingの逆で、元のデータから引き伸ばす。

### Skip / Residual
複数前の情報を使って、複数層スキップして結合する方法。ResNetで使われる。

<img width="300" alt="ResNet.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/223a5fe9-7bf7-e92c-9275-a6142ed9e789.png">

### Dilated Convolution　/ Atrous Convolution　/ Convolution with holes
畳み込みの積和計算を、間をあけて計算して出力する。


# 代表的な手法
## CNN
隠れ層に畳み込み層とプーリング層をもつもの。

### フィルタ (filter) / カーネル (kernel) / 特徴検出器 (feature detector) 
畳み込みを行うスライド窓のこと。

### ストライド (strides)
フィルタをいくつ移動させるか。フィルタの適用する位置間隔。

### zero padding
周りを0で埋めて、端のデータの特徴もちゃんと捉えられるようにする。また、出力サイズを調整することも可能。

### 特徴マップ / feature map
畳み込み層の出力データのこと。

### チャンネル
ここ↓ の次元。グレースケールはチャンネル1。RGBカラーはチャンネル3。

<img width="100" alt="Screenshot 2018-03-13 14.47.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/03fb14c1-bcba-6d91-b055-3984bd9c96e2.png">


## 転移学習(transfer learning) / 再学習(Fine-tuning)
一度、学習した重み（学習済みモデル：Pre-trained Model）を利用して、再度学習をおこなうこと。

## RNN / リカレントニューラルネットワ / 再帰型ニューラルネット/ 回帰型ニューラルネット
時系列データ、前後のデータに意味のあるデータに対して、その特徴を学習できるもの。
中間層に出力を自らの入力とする帰還路をもつ。
ただし、長期的な特徴を学習することは困難。

## LSTM
時系列データにおいて、RNNより長期のデータの特徴を学習できるディープラーニング。
RNNの中間層をLSTM-Blockと呼ばれる、状態を記憶するメモリセルと、記憶を制御する忘却ゲートをもったものに置き換えられたもの。

## VAE(Variational Autoencoder)
データの潜在変数 $z$ を確率分布とした、生成モデル。
入力データをニューラルネットで潜在変数に変換し（Encode）、潜在変数からまたニューラルネットで入力データと同じ空間に変換（Decode）して新たなデータを生成する。

## GAN(Generative Adversarial Network) / 敵対的生成ネットワーク
データを生成するニューラルネット（generator）と、データが本物データかgeneratorによって生成されたデータかを識別するニューラルネット（discriminator）を使った、生成モデル。

## R-CNN
物体検知の代表的な手法。[Selective Search](https://qiita.com/Almond/items/7850cf81903fbe2a2c6c#selective-search%E3%81%A8%E3%81%AF)で物体候補を探し、CNNによって対象部分の特徴mapを生成して分類する。

## YOLO
物体検知において、End-to-Endで学習可能な方法。はじめにグリッドにデータを分割しておき、そのセルごとに分類とボックスの位置・縦横の回帰を行う。

# フレームワーク
### Tensorflow
ディープラーニングの実装において、世界でもっとも利用されているテンソル計算用のフレームワーク。
Googleが開発。計算グラフを記載して走らせる、Define and Run。
ソースコードを変更しなくてもGPUを利用できる。

### Keras
Tensorflowのラッパーで(Theano/CNTKもバックエンドに使える)、実装が非常に容易なので初心者におススメ。
レイヤーを重ねるだけでネットワークを構築でき、非常に直感的。
Tensorflowに続き、人気No2。

### Chainer
日本の企業Preferred Networksが開発した国産フレームワーク。動的に計算グラフが構築できるDefine by Runで、計算グラフが記載しやすい。Pythonで記載されている。

### Pytorch
最近人気が出てきているフレームワーク。ChainerのForkで、facebookが中心に開発。
研究者の利用が多く、非常に高速でコードの記載も難しくない。

### Caffe / Caffe2
古くからあるフレームワーク。非常に高速だが、記載するコードが長くなる。

### Theano
Python用ディープラーニングの元祖フレームワーク。しかし、開発が終了するそうです。

### CNTK
Microsoftが開発しているがオープンソース。当初C++しか使えなかったが、現在はPythonも使えるようになっている。複数台でのGPU処理が得意。

### Deeplearning4j
JVM上で動くディープラーニングのフレームワークでJavaやScala用。HadoopやSparkと連携できる。

### [ランキング](https://github.com/thedataincubator/data-science-blogs/blob/master/output/DL_libraries_final_Rankings.csv)
<img width="900" alt="Screenshot 2018-03-13 14.52.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/105335/36763d69-74b3-75d3-54dc-cd5ee4c2eef4.png">

# 環境
### CUDA
NVIDIA社が出しているGPUを使うための統合開発環境。

### Colaboratory
Googleドライブにて環境構築なしでJupyter notebookにてGPUを利用できるサービス。
時間制限はあるが、無料でGPUを利用できる。


# おわり
辞書というにはまだ貧弱なので、これから更新していきたいです。
誤りがありましたら、ご指摘いただけたら嬉しいです。


# 参考
[Visualising Activation Functions in Neural Networks](https://dashee87.github.io/data%20science/deep%20learning/visualising-activation-functions-in-neural-networks/)