DeepLearning概論

ディープラーニングについて薄く広い理解ができるようなメモ。
学習した内容に応じて随時追記しています。

# ディープラーニングでできること
- 画像認識、変換、生成
 - 姿勢推定
- 自然言語処理
 - 翻訳
- 音声認識
- 強化学習

#しくみ
##単純パーセプトロン
ニューラルネットワークを構成する基本単位。
1つ以上の入力を受け取り、それらの重み付け和から活性化関数を通して出力。
非線形な問題が解決できない。

##多層パーセプトロン
英: Multilayer perceptron、略称: MLP
少なくとも3つのノードの層からなる。
入力ノードを除けば、個々のノードは非線形活性化関数を使用するニューロンである。
万能近似理論に従い、非線形な問題も解決できる。

###万能近似定理
定数でない連続な有界単調増加の関数を隠れ層の出力に使った3層以上のニューラルネットワークは任意の連続関数を任意の精度で表現可能。
ただし、層が少ない場合にはユニット数が指数的に増加するため、現実的には層を深くする必要がある。

###活性化関数
非線形モデルの解決のため、活性化関数が用いられる。
中間層の場合は必ず微分可能で非線形である必要がある。
また、勾配消失を起こしづらいほうが中間層を重ねられる。
tanhやReLU等が存在する。

####線形ユニット
出力がガウス分布に基づくという前提。
非線形変換を伴わない。アフィン変換がなされる。
回帰タスクにおける出力層等で用いられる。

####シグモイドユニット
出力がベルヌーイ分布に基づくという前提。
出力範囲が0-1に収まるため、2値分類における出力層で用いられる事が多い。
微分した値が小さくなりやすく、勾配消失が生じるため中間層には向かない。

####ソフトマックスユニット
出力がカテゴリカル分布に基づくという前提。
多値分類の出力層で用いられる事が多い。
ソフトマックス関数はn=2の場合にシグモイド関数と一致する。

####tanh
微分した値が小さくなりやすく、勾配消失が生じやすい。

####ReLU
正規化線形関数
勾配が消失せず、計算コストが低く、非線形性が強いため性能が良い。
x=0にて非連続であるためx=0では微分可能ではないが、0を境界にすれば微分可能。
Leaky ReLU、RReLU、Parametric ReLU等の亜種がある。

####Swish
ReLUに似た形だが、非連続な点がないため、0近辺においても導関数がなめらか。

##コスト関数、損失関数
最適な重みに近づくための指標。
「正解」と「計算結果」との誤差を表すもので、この値が最も小さくなるように重みを最適化させる。
ディープニューラルネットワークのコスト関数は非凸関数なので、非凸最適化を解く必要がある。
交差エントロピー誤差等が利用される。

###交差エントロピー誤差
交差エントロピー誤差を算出する関数の形は選択される活性化関数に応じて異なる。
また、その導出には最尤推定を用いることができる。

###凸最適化
最適化問題の分野のひとつで、凸集合上の凸関数の最小化問題。
局所的な最小値が大域的な最小値と一致する。

###非凸最適化
局所的な最小値が大域的な最小値と一致しない。
ディープニューラルネットワークの最適化は、非凸最適化。

###局所解
局所的な最小値。勾配が0となるため、それ以上学習が進まない。

###鞍点
ある次元では極大、別の次元では極小となる点。
局所解同様に最適解ではないものの勾配が0となる。

###flat region
傾きが小さい平坦な領域であり、学習が進みづらい。
鞍点の周辺はこのようになっている事が多い。

###崖、勾配爆発
傾きが大きい箇所(崖)があると、パラメータが大きく動いてしまう。
更新幅を小さく制限する方法で緩和できる。(勾配クリッピング)

#学習(重みの最適化)
##最急降下法
関数の傾きのみから、関数の最小値を探索する連続最適化問題の勾配法の一つ。
勾配を求めるため、関数が微分可能である必要がある。

##確率的勾配降下法
英: stochastic gradient descent, SGD
単純な最急降下法に比べて極小値に陥る可能性が低い。
ランダムにサンプリングしたデータと損失関数から逆算した各ノードの傾きをもとめ、重みを調整するという作業を十分な回数繰り返す。
算出される傾きはデータに依存するが、データをランダムサンプリングすることで都度算出される傾きにばらつきが生じ、局所解に陥りづらくなる効果がある。

また、SGDはフラットな谷に到達する確率が高い。(フラットな谷はシャープな谷よりも良いとされる)
RMSPropやAdam等、SGMの改良アルゴリズムが存在する。

###Momentum
過去の更新ベクトルを参照し、パラメータの更新を特定の方向に加速させる。
ずっと同じ方向にパラメータが更新され続けているのであれば、思い切って大きめにパラメータを更新してもよいはず、というアイディアに基づく。
パラメータの更新がより早く収束する可能性がある。

###NesterovのMomentum
Momentumを改良し、パラメータの更新が早く進みすぎないように補正している。

###SGMの改良アルゴリズム
####AdaGrad
SGMの改良版。各パラメータごとに異なる学習率を使う。

####RMSProp
AdaGradの改良版。
AdaGradは学習率の減衰が過大気味になるので、減衰しすぎないようにしている。

####Adam
AdaGradとRMSPropの良いとこ取り
Adamは良い解が近くにあるのに、むしろそこから遠ざかってしまうようなパターンが存在する。

####AdaBound
Adamに学習率の上限と下限を動的に加えたものをAdaBound。
最初はAdamのように動き、後半からSGDのように動く。

####AMSBound
AMSGradに学習率の上限と下限を動的に加えたものをAMSBound。
最初はAdamのように動き、後半からSGDのように動く。

##重みの初期値
初期値によっては極小値で停滞してしまい、最小値にたどり着くことができないことがある。
過学習を避けるためには小さいほうが良い。
その他にも、初期値の選択によってアクティベーションが偏りネットワークによる表現が狭くなる、勾配消失が生じる等の弊害が生じるため適切な選択が必要。

###Xavierの初期値
各層のアクティベーションが同様の広がりの分布になるように、前層のノードがn個のとき、平均0,標準偏差$$\frac{1}{\sqrt{n}}$$である正規分布から初期値を生成する、というもの。
シグモイド関数と相性が良い。

###Heの初期値
標準偏差
$$\{\sqrt\frac{2}{n}}$$
である正規分布から初期値を生成する。
ReLU関数と相性が良い。

##学習手法
###バッチ学習
全ての学習データを使って損失計算を行い、重みを更新する方法。
すべてのデータをメモリに展開する必要があるため、計算資源を多く必要とする。

###ミニバッチ学習
ランダムにn個のデータを選び、その単位で計算する方法

###オンライン学習
ランダムに1個づつデータを選ぶ。DLでは通常は選択されない。
1データごとに計算するため、重みの更新が安定しない。

###転移学習
別のタスクを学習したネットワークを利用して、新しいタスクに転用するという手法。
出力層以外の学習済みモデルの重みは固定し、追加した出力層のみを新たなデータセットを用いて学習します。
CNNは初期値依存性が高く転移学習と相性がよい。

###ファインチューニング
別のタスクを学習したネットワークの層の重みを微調整する手法。


##誤差逆伝播法
パラメータを一つづつ変更して損失計算を繰り返すフォワードプロパゲーションではパラメータの数が多い場合には計算量が膨大になり処理速度が遅いという問題があり、実用的ではない。
大きなネットワークでも損失関数の微分を効率よく計算するための手法が誤差逆伝播法。

各パラメータが変更された際に損失がどの程度増減するかを、損失関数をパラメータで偏微分した値を各パラメータに対して計算した値と、連鎖律(合成関数の微分)を用いて算出するため、フォワードプロパゲーションに比べて効率よく計算ができる。

連鎖律を用いる際に、各ノード毎に計算を分解したものを計算グラフと呼ぶ。

処理の順序は下記のとおり。
入力層から出力層まで、入力と重みの内積を求めて出力層の出力を得る
損失関数の各出力層に対する微分を求める
微分結果を連鎖律を利用して逆伝播させ、全ての重みに対して勾配を求める
勾配をもとに重みを更新する

##過学習
訓練データに適合しているが、未知のデータに適合できてない状態。
以下のような方法で過学習を抑制する。

###正則化
損失関数に正則化項を追加し、重みが大きくなりづらくすることで過学習しづらくする。
有名なのはL1正則化(Lasso)とL2正則化(Ridge)
そのほか、モデルにノイズを加える方法もある。Dropout等、学習を邪魔すること。

###Data Augmentation
データ量を増やして過学習しづらくする。
画像の場合、上下左右の反転や、拡大縮小、回転、色の返還等によりデータを増やすことができる。
ただし、文字認識の場合に別の文字になってしまうことも考慮が必要。

###Dropout
ネットワークのうち何割かのノードを一時的に削除(無効化)し、学習するたびに無効にするノードは変更する。
一般的には無効にするノードの割合(Dropout率)は50%。
ランダムにノードを無効化するため、異なるネットワークによるアンサンブル効果(bagging)が得られる。

###半教師あり学習
ラベルなしデータの活用。
ラベルなしデータも含めて疎な箇所で分類する。

###マルチタスク学習
単一のモデルで複数のタスクを解く手法。
タスク間の共通の要因を獲得し、課題の予測精度を向上させます。

###Early Stopping
validation loss が上昇に転じ始めたら学習を打ち切る方法。
学習時間の節約も可能。

###パラメータ共有
パラメータ数が大きく削減でき、高速化や汎化性能の向上が見込める

###アンサンブル学習
弱学習器を組み合わせて汎化性能を向上させる手法。
低バイアス、高バリアンスなモデルを組みあわせることでより性能が高まる。

####Bagging
各学習器に使う学習用データをブースストラップサンプリングによって得て、その学習したモデルを予測に用いて最後アンサンブルするという手法。
各学習器の多数決によって最終的な出力を決める、もしくは各学習器の中で最も確率を高く予測した結果を用いる。

####Boosting
弱い学習器を直列に学習させて、より精度が向上するように修正していく手法。

##前処理、正規化
データを前もって扱いやすい形に変換すること
たとえば各特徴の値が-1～1の間に収まるようにするなど。
Deep Learningにおいては、入力は白色化することが一般的。
また、中間層においても適切に正規化をすると性能が上がる。

###標準化
データから平均を引いて標準偏差で割ることで平均=0、標準偏差=1とする　$$Z = (X-μ)/σ$$

###無相関化
各次元のデータがまんべんなく活用されるよう、データの各次元間の相関を無くす。

###白色化
無相関化し、標準化すること。

###共変量シフトの解消
通常機械学習では訓練データの分布とテストデータの分布が等しい事を仮定するが、現実には異なる事もある。この状況を共変量シフト(covariate shift)と呼ぶ。
予め共変量シフトを解消しておくことで学習が効率化される。

###Batch Normalization
各バッチ、各層ごとに毎回平均と分散の正規化を行う。
共変量シフトが解消されるため学習率を上げても学習できる。
L2正則化、Dropoutの必要性が下がる。


##教師あり事前学習
suprevised pre-learning
多くは貪欲法に準拠したアルゴリズムとなる。
現在は多層ニューラルネットを安定して学習する方法が発展してきたためほぼ使われない。

###貪欲法
最適化問題を解くとき，計算の各段階で最も利益の大きい部分解を選んでいき、それらの部分解を組み合わせたものを最終的な解とする手法。
具体的には学習が終わったネットワークは固定しながら逐次新しい層を追加しながら学習する方法。

###再学習、ファインチューニング
学習済みモデルの層の重みを微調整する手法です。 
学習済みモデルの重みを初期値とし、再度学習することによって微調整します。

#DeepLearningの実践的手法
##CNN
英: Convolutional Neural Network
CNNは、畳み込み層やプーリング層によって得られた特徴マップの各ピクセルデータを、ニューラルネットワークの入力値として利用する。
画像認識に活用される。

CNNは大きく分けて2つのパートに分けることができる。

1つ目は、画像を読み込み、畳み込みやプーリングによって特徴マップを作成する特徴量抽出パート
2つ目は、全結合層を繰り返すことで最終的な出力を得る識別パート

畳み込みでは入力となる画像を小さなフィルタを利用して畳み込んでいく。
具体的には入力となる画像とフィルタの内積を計算し、その結果をアウトプットする。

活性化関数には主にReLUを利用。

特徴として転移学習と相性が良く、自動車を認識するCNNはトラックや飛行機の認識に流用できたりする。

###できること
####Semantic Segmentation
画像内の全画素にラベルやカテゴリを関連付ける。
物体と背景との境界を切り分けて認識する。

####Object Detection
物体検出。画像ファイルに含まれる物体の種類と、画像内の位置を検出することができます。

####Instance Segmentation
物体の領域をオブジェクトごとにピクセルレベルで検出および分類する手法。
Object Detectionのように物体の数量を判断でき、尚且つSemantic Segmentationのようにピクセルレベルの厳密な領域分割ができる。

###畳み込み
####フィルタ、カーネル
フィルタのサイズは3×3～11x11px程度とかなり小さい。
フィルタを利用して畳み込むという処理はパラメータ共有と同じ。

重みは手動で設定する場合もあるが、CNNではバックプロパゲーションで求めることでタスクに沿った有用なフィルタが獲得できる。

####padding
畳み込みを繰り返すについて、画像サイズが小さくなるが、層を重ねる上では不都合がある。
paddingを利用することで画像サイズの縮小を回避できる。

#####zero-padding
畳み込むときだけは「画像の周りに0埋めの余白がある」と考えて畳み込む

####出力チャンネル数
フォルタの個数と出力チャンネル数は一致する。
例えば、2チャンネルの入力、フィルタが4つあれば、出力は4チャンネル。

####出力サイズ
- p: パディングサイズ(padding size)
- k: フィルタサイズ(filter size, kernel size)
- s: ストライド(stride)
とした際に
- h’, w’: 出力サイズ
は以下の数式から算出できる。
$$h’ = (h + 2p - k) / s + 1$$
$$w’ = (w + 2p - k) / s + 1$$

####Dilated Convolution
特殊な畳込み処理。
畳み込まれる画像領域を読み込む際に、隣り合った画素を読み込むのではなく、間隔を開けて読み込む。
これにより、例えばフィルタサイズが3×3の読み込みであってもより広い領域(5×5等)を一度に読み込むことができる。
かつ、広いフィルタと同じ広さをカバーしつつ、計算量は3×3フィルタと同様。
そのため、広い範囲の情報を見ないといけないようなタスクだと有効。

####UpConvolution
特殊な畳込み処理。
入力画像を0埋めで拡大してから畳み込むので、逆に画像を大きくする畳み込み処理。
Semantic Segmentation などではよく利用される。

####1x1 convolution
チャンネルの圧縮に利用される。

####im2col
畳み込み計算を効率的に実施する手法。
画像(image)中の長方形の領域を行列の列に、フィルタの領域を別の行列の行に変換し、それらの内積を計算する。
行列の計算なのでGPUを利用した高速処理が可能になる。

###Pooling
畳み込みは3x3など非常に局所的な処理しかしないが、画像認識においてはより広い範囲の情報が必要であるため、大域的な情報を見るために画像を縮小する。
これにより特徴の並進移動に頑健になる。

####Max Pooling
ウインドウ内の最大値を出力とする。
基本的にはこちらの手法が選択される。

####Average Pooling
ウインドウ内の平均値を出力とする。

###CNN固有の正則化手法
####Stochastic Depth
Residualブロック自体をDropoutする。
通常のDropoutは横方向にネットワークを小さくするが、深さ方向にネットワークを小さくする。
モデルの深さが浅くなるため、訓練時間が短くなり、勾配消失が発生しづらくなる。
また、モデルのアンサンブルのような働きがあるため、精度も向上する。
出力に近い層のDrop率を高めるほど精度が向上する。

####Shake-Shake Regularization
Residualブロックのネットワークを2つに分岐させ、それぞれのネットワークの畳み込み処理の順方向の出力にα、1-αを乗じた値を出力とする。
また、逆伝播時にはβ、1-βを入力値に乗じた値を入力とする。
学習のエポック数は6倍程度必要になるが、精度がかなり向上する。

####mixup
Data Augmentationの方法であり、複数画像を重ね合わせた画像を訓練データとする手法。

Xを作成される画像データ、yを正解ラベルとすると以下のように表される。
λはλ∈ [0,1]:　ベータ分布 B(a, a) からのサンプリングで決める。

```math
X=λX_{1}+(1-λ)X_{2}
```
```math
y=λy_{1}+(1-λ)y_{2}
```

####Cutout
Data Augmentationの方法。
元画像の一部分を正方形で隠す。
隠された領域の色は平均値。
https://arxiv.org/pdf/1708.04552.pdf

####Random Erasing
Data Augmentationの方法。
画像の一部を矩形のノイズで隠す。

###コードサンプル
####mnistに対するCNN実装
mnistの手書き数字の画像データセットを利用してCNNの実装を行ったコードを記載します。
VGG16のように16層つなぎたかったのですが、元画像の画素数が小さかったため、畳込みとプーリングが少なめになっています。

```python
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten
from keras.optimizers import RMSprop

import cv2
import matplotlib.pyplot as plt
import numpy as np

(x_train_origin, y_train_origin), (x_test_origin, y_test_origin) = mnist.load_data()
x_train=x_train_origin#28×28=784点からなる60000枚の画像
y_train=y_train_origin
x_test=x_test_origin#28×28=784点からなる10000枚の画像
y_test=y_test_origin

x_train = np.array([cv2.resize(src=img, dsize=(img_rows, img_cols)) for img in x_train_origin])#画像サイズを32×32へ変換
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)#次元の変換　img_rows×img_cols点のデータ60000枚。グレースケールなのでチャンネルは1

x_test = np.array([cv2.resize(src=img, dsize=(img_rows, img_cols)) for img in x_test_origin])
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)

x_train = x_train.astype('float32')   # int型をfloat32型に変換
x_test = x_test.astype('float32')
x_train /= 255                        # [0-255]の値を[0.0-1.0]に変換
x_test /= 255
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()
# CNN を記載 VGGっぽい実装
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding="same", input_shape=(img_rows, img_cols, 1)))#input_shapeは画素縦×画素横×チャンネル数 RGBではなくグレースケールなのでチャンネルは1
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.summary()
model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(),
              metrics=['accuracy'])

history = model.fit(x_train, y_train  # 画像とラベルデータ
                    ,batch_size=batch_size
                    ,epochs=epochs     # エポック数の指定
                    ,verbose=1         # ログ出力の指定. 0だとログが出ない
                    ,validation_data=(x_test, y_test)
                    )

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

loss     = history.history['loss']
val_loss = history.history['val_loss']

nb_epoch = len(loss)
plt.plot(range(nb_epoch), loss,     marker='.', label='loss')
plt.plot(range(nb_epoch), val_loss, marker='.', label='val_loss')
plt.legend(loc='best', fontsize=10)
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
```

###有名なCNN
####Alex Network
DLブームを起こした有名なモデル。
最新のモデルと比べて精度が低いので現在は使われてない。

####VGG16
畳み込み13層とFC3層の計16層。
Alex Networkの反省を活かしCNNの基本形を作った。
フィルタサイズを小さく、層を何度か繰り返すことで、同じ受容野の大きさでパラメータ数を減らせる。
また、情報が失われすぎるのでpoolingのウィンドウサイズは大きすぎないほうが良い、等。

VGG16が提案した指針として、以下のようなものがある。
フィルタサイズを3x3とし、畳み込みを何度か繰り返す
max pooling を1回行い、特徴マップを1/2に縮小する
pooling後はチャンネル数をそれまでの倍にする

####GoogLeNet
Inceptionモジュールを繰り返した複雑なネットワーク。
22層あり、誤差の伝播が難しくなっているが、Auxiliary Lossを取り入れ、途中からも誤差逆伝播させることで誤差信号が減衰しないようにする。

#####Inceptionモジュール
複数の畳み込み層（1×1, 3×3, 5×5）を並列に適用し、それぞれの畳み込み計算の結果を最後に連結している。
スパースな畳込み。

#####1×1 Convolution
入力画像のサイズを変えずに、チャンネルの数を変更する畳み込み操作。
出力される特徴マップのチャンネル数を任意の数に減らすことができる。
これによって計算量が削減される。

#####Auxiliary Loss
ネットワークの途中から分岐させたサブネットワークにおいてもクラス分類を行い、auxiliary lossを追加する。

#####Global Average Pooling
入力された特徴マップのサイズと同じサイズのaverage poolingを行うpooling層。
1×1×入力チャンネル数のテンソルが出力され、その出力をソフトマックス関数にかけ、多値分類を行う。
畳み込み層の後に用いられる全結合層の代わりとして用いることでパラメータの削減ができ、計算量や過学習のリスクを軽減できる。

####Residual Network（ResNet）
残差ネットワーク。現在のCNNのベース。
一般的に層が深いほど精度が高まると考えられているが、50層を超えるような大きなネットワークは性能が低下する事がわかっていた。
Residual blockを活用し、多層化の問題を解決したネットワーク。ImageNetコンペティションで優勝した時は152層のネットワーク。
学習時間が極端に長い。

#####Residual block
畳み込み層とそれらを迂回するShortcut Connection(あるいは Skip Connection とも呼ばれる）の組み合わせによって成り立つ。
Shortcut Connectionからは入力xと同じ値が出力されるため、畳み込み層では期待される出力yと入力xとの差(残差)を求める構造となっている。

CNNはパラメータ共有を行っているため恒等写像が難しいがShortcut Connectionにより層をスキップする構造となっているため、恒等写像を実現しやすい。
また、Shortcut Connectionにより勾配消失が起きづらく、加えてResidual blockを経由する経路、経由しない経路が併存する形となり、それら複数経路のアンサンブル効果も期待できる。
なおかつ、パラメータや計算コストがほとんど増えない。

Residual blockにはPlainアーキテクチャ、Bottleneckアーキテクチャの2つの実装方法が紹介されている。
いずれも計算コストは同じだが、層が深い分

#####Plainアーキテクチャ
3×3の畳み込み層が2つある。

#####Bottleneckアーキテクチャ
1×1と3×3の畳み込み層で出力のチャンネルを小さくしてから最後の1×1の畳み込み層でチャンネル数を復元する。

#####WideResNet
ResNetの亜種。
多層にするのではなくWideにして学習速度、精度の向上を目指す。

#####PyramidNet
ResNetの亜種。
出力する特徴マップのチャンネル数を増加させる層は他の層と比べて影響が大きくなるが、特定の層のみに影響が偏ることを避けるため、全てのResidual blockでチャンネル数を段階的に上げる。
また、Residual block自体も改善し、Single ReLUを採用。

#####ResNeXt
ResNetの亜種。Residual blockを改善。
Residual block内で入力を分岐させて、並列で処理を行う。
並列数をcardinalityと呼ぶ。

#####Xception
ResNetの亜種。Residual blockを改善。
通常の畳込みをdepthwise畳み込みとpointwise畳み込みの2つの処理にわける。

depthwise畳み込みはK×Kのフィルタを1つ利用することで出力を1チャンネルに絞り、その後ウインドウサイズ1×1のフィルタN個によるpointwise畳み込みにより出力チャンネル数をNに復元する。
これによりK×KのフィルタをN個利用する畳み込みに比べて、パラメータや計算量を削減することができる。

#####EfficientNet
ResNetの亜種。
解像度・深さ・チャネル数をグリッドサーチにより同時に最適化。高速かつ高精度なネットワークを構築。
活性化関数にReLUではなくswishを利用している。

#####Assemble-ResNet
ResNetの亜種。
EfficientNet B6+AutoAugと同等程度の精度で5倍早い。
アーキテクチャにResNet-D、Selective-Kernel、Anti-Alias Downsampling、Big Little Network
正則化手法にLabel Smoothing、Mixup、DropBlock、Knowledge Distillation、AutoAugment
を採用。

####Dence Net
n個飛ばしのShortcut Connectionを採用。(ResNetは1個飛ばし)
精度は高くなるのだが、パラメータ数が増え、計算処理が重くなる。

####FCN
英: Fully Convolutional Network
CVPR 2015, PAMI 2016で発表された Fully Convolutional Networks for Semantic Segmentationで提案されたSemantic Segmentation手法。
ピクセル単位でのクラス分類を行うSemantic Segmentation手法。
出力ユニット数は画像サイズ×分類クラス数。
全結合層を持たず、全結合層は1×1の畳み込み層に置き換えられており、ネットワークが畳み込み層のみで構成されている。

####U-Net
FCNの一種。
畳み込まれた画像をdecodeする際、畳み込まれた画像に対してskip-conectionによりencode時の出力である特徴マップを重ね合わせている点が一般的なFCNと異なる。
畳み込みによって失われた情報をskip-conectionにより補完している。

####R-CNN
Regions with CNN features
Object Detectionを行うアルゴリズムで、イメージ内のオブジェクトを検出して分類する。
2段階のアルゴリズムとなっており、第1段階でオブジェクトを含んでいる可能性のあるイメージ内の領域を特定(Region Proposal)&固定サイズの画像にリサイズし、第2段階でその画像に含まれるオブジェクトをCNNを用いて分類します。
Selective Searchによって領域を提案し、その提案された画像のサイズを調整し、その画像に対して複数回CNNを実施する、という処理の流れのため処理が重い。

領域の特定にはSelective Searchが用いられるが、計算コストが高い。
Selective Searchとは画像内の類似のピクセルをグループ化するアルゴリズム。


####SPPnet
SPPとはSpatial Pyramid Poolingの略。
SPPでは、特徴マップを異なるサイズのウィンドウ(16×16, 4×4, 1×1)でmax-poolingした結果を平坦化して連結し、固定長のベクトルとして出力する。
SPPは矩形領域のサイズに関わらず固定長のベクトルを得ることができる。

SPPnetではCNNのConv&Pool処理によって出力される特徴マップをベースに、その特徴マップにRegion Proposalを投影した領域にSPPを実施し、次の全結合層の入力とする。

特徴マップ作成後にRegion Proposalを行うことで、都度Conv&Pool処理を行う必要がなくなり、処理が高速化される。

####FAST R-CNN
FAST R-CNNとはSPPnetをベースにRoI Poolingやmulti-task lossを導入している。

RoI Poolingでは、Conv,pool処理後のfeature mapから、region proposalにあたる領域をうまく「固定サイズのfeature map」として出力。
具体的には元画像のregion proposalの領域をfeature map上に投影した際に生じるfeature map上のピクセル格子とのずれを丸め込みながらPoolingする手法。
RoI Poolingによって固定サイズ化された領域は、全結合層(Fully connected layers)を経てRoI feature vector(RoI特徴ベクトル)となる。このRoI feature vectorを、以下2つの全結合層の入力とする。

表示物体の分類(Classification)タスクを学習する全結合層
表示位置の回帰(Regression)タスクを学習する全結合層

multi-task lossとは１つのネットワークで複数のタスクを解くモデル。
FAST R-CNNでは表示物体の分類と表示位置の回帰とを同時に解決している。

分類にはクロスエントロピー、回帰にはSmoothL1ノルムを損失関数としている。

RoIを求める処理がニューラルネットワークとは独立したSelective Searchで行われている点が欠点。

####Faster R-CNN
FAST R-CNNを改善しResion ProposalをSelective SearchではなくResion Proposal Network(RPN)によって実装している。
全てBackpropで計算できるようになった。

RPNはそれ自体が「ある画像のどこに物体が写っているか」=「物体が写っている場所と、その矩形の形」を検出できる機械学習モデル。

詳細
https://medium.com/lsc-psd/faster-r-cnn%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8Brpn%E3%81%AE%E4%B8%96%E7%95%8C%E4%B8%80%E5%88%86%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E8%A7%A3%E8%AA%AC-dfc0c293cb69

####YOLO
Faster R-CNNとは異なり、領域候補の抽出と物体認識を同時に行う。
入力画像をS×S個のグリッドセルと呼ばれる領域に分割し、それぞれのグリッドセルについてB個のバウンディングボックス(boundhing box)を作成し、その各ボックスに対して信頼度スコア(confidence score)を推測する。
信頼度スコアはバウンディングボックスに物体が含まれているかを示す。

並行してグリッドセルに対して条件付きクラス確率(conditional class probabilities)を算出する。
信頼度の高いバウンディングボックスに対して、ボックスに対応するグリッドセルの保持する条件付きクラス確率を用いてボックスのクラスを決定する。

領域の確定と物体の判別を同時に行うため、処理が早い。リアルタイムでの処理も可能。
しかし、小さい領域の検出ができないことや精度が劣る点がデメリット。

####SSD
Single Shot Detector
YOLO同様、領域候補の抽出と物体認識を同時に行う。
物体の検知はデフォルトボックスをもとに行う。
特徴マップをn×nに分割し、分割した各セルにアスペクト比が異なる複数のボックス(デフォルトボックス)を考え、損失関数とjaccard係数から正解に近いボックスを選択する。
また、この作業はExtra Feature Layersの中で特徴マップを畳み込みながら異なる分割領域数(10×10→5×5等)を特徴マップにあてがい行われる。

損失計算の際にはHard negative miningを行っている。
「すべて背景領域である」という判定をしても損失を下げることができてしまうので、負例と正例が最大でも3:1にしかならないような調整している。

##RNN
Recurrent Neural Network
主に時系列処理(音声、テキスト、株価などの時間的な変化を表すデータ系列)に用いられる手法。
RNNの基本的な構造は、「現在入力値と前回の出力値を合計し、活性化関数を適用して現在の出力＆次回の入力として出力とする」という流れ。

ただ、RNNは過去から繋がったネットワークとなっており、長い系列を学習しようとするとネットワークが大きくなるため、古い情報に対する逆伝播時に勾配消失、勾配爆発が起きてしまい、古い情報がモデルの学習に寄与しなくなってしまう。

###LSTM
Long-short term model
従来のRNNでは学習できなかった長期依存(long-term dependencies)を学習可能なモデル。
RNNに比べて、以下のような改善がモデルに加えられている。

CEC(Constant Error Carousel)：過去のデータを保存するためのユニット
入力ゲート：「前のユニット(1つ前の時間のユニット)の入力をどの程度受け取るか」を調整するためのゲート
出力ゲート：「前のユニット(1つ前の時間のユニット)の出力をどの程度受け取るか」を調整するためのゲート
忘却ゲート：「過去の情報が入っているCECの中身をどの程度残すか」を調整するためのゲート

####入力重み衝突(input weight conflict)
RNNでは以下のような矛盾する重みの更新が多発するため、学習が進まない要因となっていた。
1.$x$が入力されたことを示す情報を次のユニットに伝達するために$w$の値を大きくする
2.無関係な情報を伝達しないため$w$の値を小さくする

LSTMでは入力ゲートを導入し、入力ゲートを構成する重みパラメータを別途設けることで、「前のユニット(1つ前の時間のユニット)の入力をCECが受け取るか否か」を判断させるようにしている。

####出力重み衝突(output weight conflict)
入力重み衝突と同じジレンマが出力側にも存在するため、LSTMではCECからの出力を次のユニットが受け取るか否か、を判断するための出力ゲートとそれを構成する重みパラメータを設けることで回避している。

####peephole connection
入力、出力、忘却ゲートの判断にCECで保持している情報も活用できるように、CECからの接続を各ゲートに設ける。

####勾配クリッピング
LSTMでは勾配爆発に対しては対応していないので、RNNの勾配爆発は重み行列のスペクトル半径(固有値の絶対値の最大値)に依存するという性質を利用して、勾配クリッピングを行うことで対応。

###Bidirectional LSTM
通常のRNNと異なり、過去の入力を利用するだけではなく未来の入力も利用する。

###GRU
Gated Recurrent Unit
LSTMを簡略化したモデルで、メモリセルをなくし、忘却ゲートと入力ゲートを合体し、更新ゲートとしている。

###Sequence-to-sequence
機械翻訳に利用されているモデル。
エンコーダーとデコーダーそれぞれにLSTMを利用しており、翻訳元の文章がエンコーダーに入力され、エンコーダーから出力されるベクトルをデコーダーで「次の単語」を予測するタスクを解くことで翻訳先の文章に戻される。


##GAN
英: Generative Adversarial Networks
敵対的生成ネットワーク。
GANは生成モデルの一種であり、データから特徴を学習することで、実在しないデータを生成したり、存在するデータの特徴に沿って変換できる。

##DeepRL

英: Long short-term memory
時系列データ(sequential data)に対するモデル。