深層学習(勾配消失問題～CNN)

※以下、個人的な勉強のためのレポートです。
※間違い多々あると存じますが、現在の理解レベルのスナップショットのようなものです。
※勉強のためWebサイトや書籍からとても参考になったものを引用させていただいております。
http://ai999.careers/rabbit/
※書籍「ゼロからつくるDeep Learning」を参考にさせていただいております。

# 連鎖律の復習
連鎖律の原理を使い、dz/dxを求めてみる
z=t^2、t=x+y
※合成関数の微分の多変数関数への拡張
https://ja.wikipedia.org/wiki/%E9%80%A3%E9%8E%96%E5%BE%8B
複数の関数が合成された合成関数を微分するとき、その導関数がそれぞれの導関数の積で与えられるという関係式
連鎖律とは，高校数学で習う合成関数の微分公式を多変数関数に拡張した公式。
例えば，2変数関数の場合，以下のようになる

z=t^2
t=x+y

dz/dx=dz/dt*dt/dx
z=t^2
t=x+y
dz/dt=2t
dt/dx=1
dz/dx=2t*1
=2t
=2(x+y)

# 勾配消失問題
誤差逆伝播法が下位層(出力層から入力層)に向かって進んでいくにつれて、勾配がどんどん緩やかになっていく。そのため、勾配降下法による更新では下位層のパラメータはほとんど変わらず、訓練は最適値に収束しなくなる。

勾配消失問題の一例として、シグモイド関数の微分を考える

シグモイド関数を微分した際、入力値が0のときに最大値を取る。
その値として正しいものは？
f(u)'=(1-sigmoid(u))(sigmoid(u))
前の項0.5、後ろの項0.5
→0.25
このような小さい値となるため、小さい値を掛け合わせていくとだんだん0に近づく。
シグモイドの微分は、MAX値でも0.25。伝播すると0,.25*0.25でさらに小さくなる
→勾配消失問題

勾配消失問題の解決策
・活性化関数の選択
・重みの初期値設定
・バッチ正規化(2015年頃提案)
などがあげられる。

## 活性化関数の選択
→ReLU関数を使う
　シグモイド関数と違い、閾値を超えた値がそのまま出力されるので小さくなりづらい

## 重みの初期値設定
→Xavier(ザビエル)：重みの要素を、前の層のノード数nに対して、平均0、標準偏差が1/√nである正規分布から重みを設定する手法
 以下の活性化関数を用いるとき、Xavierによる初期値が有効
https://to-kei.net/neural-network/initial_value/#Xivier
　ReLU、シグモイド(ロジスティック)、双曲線正接

重みの初期値設定
→He(エイチイー)
　ReLU関数に付随させ、よりもっと勾配消失を起こさないようにする
　重みの要素を、ノード数nに対して、平均0、標準偏差が√2/nである正規分布から重みを設定。

重みの初期値に0を設定すると、どのような問題が発生するか？
→
すべての値(次に伝播する値)が同じ値で伝わるため、
パラメータチューニング行われなる。
学習の概念が阻害されてしまう。DNNがナンセンスになる。

## バッチ正規化
ミニバッチ単位へ入力値のデータの偏りを抑制する手法
活性化関数に値を渡す前後にバッチ正規化の処理を孕んだ層を加える
バッチ正規化の効果
①計算の高速化
②勾配消失が起こりづらくなる

勾配喪失問題の解決実装には、組み合わせがある
sigmoid gauss
ReLU gaess
Xavier sigmoid
He ReLU
→He ReLUが一番成績はいいが、ReLUのためにHeが開発されたから・・・ともいえるが、
Xavier ReLUとか、He sigmoidが成績がいいケースもあったりするらしい

データについて
データの取得について
例えば顔画像が欲しい・・・顔分析サービスみたいなものを立ち上げて、
顔分析API
データ集めるためにプロダクト・サービスを立ち上げる・・・とか
(日本の方がデータの管理はルーズらしい。いまのうち？)

# 学習率最適化手法

勾配降下法の復習：学習を通じて、誤差を最小にするネットワークを作成する
学習率を可変させるとどのようになるか。
大きすぎると、最適値にいつまでもたどり着かず、発散してしまう
小さすぎると、収束するまで時間がかかってしまう。大域局所最適値に収束しづらくなるでは、学習率をどう決めるか
初期は大きく設定して、徐々に小さくしていく
パラメータ毎に学習率を可変させる
学習率最適化手法を利用して学習率を最適化する
→モメンタム、AdaGrad(アダグラッド)、RMSProp、Adam

モメンタム
誤差をパラメータで微分したものと学習率の積を減算した後、現在の重みに前回の重みを減算した値と慣性（0.05-0.09）の積を加算する
局所的最適解にならず、大域的最適解となる
谷間についてから最も低い位置(最適値)にいくまでの時間が早い

AdaGrad(アダグラッド)
学習が進むにつれて、学習係数を減衰させる手法。最初は大きく学習し、次第に小さく学習する。

RMSProp
学習係数を自動で調整する最適化関数の一つ。Adagradでは学習が進むにつれて学習係数が小さくなってしまう問題があり、それを回避する手法。Adagradの問題だった学習が進むにつれて分母の合計値は増えていき学習係数が0に近づいていくことを過去何回かの合計値を近似する指数移動平均を使用することで解消する。
http://www.thothchildren.com/chapter/59b949d575704408bd43013e

# 過学習
テスト誤差と訓練誤差とで、学習曲線がかい離すること。
特定の訓練サンプルに対して、特化して学習してしまうこと。
原因：パラメータの数が多い、パラメータの値が適切でない、ノードが多いetc...
⇒ネットワークの自由度が高いともいえる

解決策
L-1正則化、L-2正則化
正則化とは、ネットワークの自由度(階層、ノード数、パラメータの値etc..)を抑制すること※限度を設けること
正則化手法を利用して過学習を抑制する

L-1正則化、L-2正則化
ドロップアウト※多く使われている

正則化
NNでは、学習データに対する誤差を定式化し誤差関数を最小化するように重み付けを最適化していく。しかし誤差ばかり最小化すると先にあげた過学習(overfitting)に陥る場合がある。
そこでこれにペナルティ項を加えて、誤差とペナルティ項を最小化するように最適化問題を解く問題に置き換えることで、「ほどよく」過学習を避けつつ穏当なモデルに落ち付かせようというのが、いわゆる「正則化」(regularization / penalized regression)の考え方である。
https://tjo.hatenablog.com/entry/2015/03/03/190000

http://d.hatena.ne.jp/keyword/%C0%B5%C2%A7%B2%BD

確認テスト
機械学習の線形モデルの正則化はモデルの重みを制限することで可能になる。線形モデルの正則化手法の中にリッジ回帰という手法がある、その特徴は？
回答：
ハイパーパラメータを大きな値に設定すると、すべての重みが限りなく0に近づく
※ハイパーパラメータ：NNでは、モデルの構成や設定はトレーニングプロセスによってある程度自動的に調整・最適化されるんだけど、一部には人間がチューニング（調整）しなければならない設定――例えばネットワークの層の数やユニット数など――があって、そういった設定をハイパーパラメーター（hyperparameter）と呼んでいる

WeightDekay(荷重減衰)
重みが大きい値をとることで、過学習が発生することがある
→学習の進行により重みのばらつきが発生する
　大きい重み→重要な値
過学習の解決策
→誤差に対して、正則化項を加算することで、重みを抑制
　過学習がおこりそうな重みの大きさ以下で、
　重みをコントロールし、かつ重みの大きさにばらつきを出す必要がある

L1,L2正則化
誤差関数にpノルムを加える
p=1の場合、L1正則化
p=2の場合、L2正則化
※L3、L4・・・もある
https://to-kei.net/neural-network/regularization/

確認テスト
よく見るL1正則化、L2正則化のグラフについて
重みw1、重みw2の2つの重みからなる重み付けベクトルの空間上に、学習データに対する誤差項の広がりを配置しこれを動かすことで誤差を最小化させることを説明しているグラフ。そこにペナルティ項を付けておくことでの定まり方が変わることを示している。左側のL1ノルム正則化であれば尖った形の領域に接するようにしなければならないため自ずとw2の軸上に最適点が定まってw1=0となり、右側のL2ノルム正則化であれば円状の領域に接するようにしなければならないためw1,w2ともにnon-zeroな値が入る。
https://tjo.hatenablog.com/entry/2015/03/03/190000

例題チャレンジ
L2ノルムは、paramの2乗、なのでその勾配が誤差の勾配に加えられる。
つまり2*param。係数2は正則化の係数に吸収されても変わらない。
よってparamが正解

L1ノルムは、paramなのでその勾配が誤差の勾配に加えられる。
つまりsign(param)である。sighは符号関数である。

# 畳み込みニューラルネットワーク(CNN)の概念
畳み込みニューラルネットワーク
画像の分野で活躍
音声データのような時系列データも加工の仕方で活用可能。

新しい概念として、「畳み込み層」「プーリング層」が登場

畳み込み層の全体像
入力値×フィルター(全結合でいう重み)→出力値＋バイアス→活性化関数→出力値

全結合の場合
MINISTの入力層784個、出力層10個

畳み込み層
画像の場合、縦、横、チャンネルの3次元データをそのまま学習し、津國伝えることができる。→3次元の空間情報も学習できるような層が畳み込み層である。これは全結合層では学習できなかったもの。
デジタル画像というのは、ピクセルというもので構成されていて、デジタル化するために分割されている。
画像データと一緒に、どんな画像データなのかを記述するためのデータが入っている。
RGBAチャンネルというのは、それぞれにグレースケール画像が入っていて、そのグレースケール画像に対して、出し方を変えているだけ。色間の相関も畳み込み層では学習できる

パディング
4*4にフィルター入れて、小さい画素になっちゃうのかといえば、
4*4に外一周囲むように0をパディングして、計算結果が4*4になるようにする
※0以外でもよい。

ストライド
フィルター演算するときのずらすマス目数

チャンネル
分解して出来た階層のこと
その階層分だけフィルターも用意する

全結合層
縦、横、チャンネルの3次元データだが、一次元のデータとして処理される
→RGBの各チャンネル間の関連性が学習に反映されない

im2col
多次元を二次元にするよく使われる関数
行列計算に落とし込むことで多くのライブラリを活用できるから
col2im
二次元配列を画像データにする

convolution class
畳み込み層

プーリング層
マックスプーリング
アベレージプーリングとがある

アベレージプーリング
対象領域の合算した平均値を出力とする
マックスは対象領域の最大値を出力とする

6*6の入力画像を2*2のフィルタで畳み込んだ時の、
出力画像のサイズは？
ストライドとパディングは1とする
→
OH(Output High)=H(hight)+2p(padding)-FH(FilterのHight)/S(ストライド)+1=6+2*1-2/1+1=7
OW(Output Width)=W(Width)+2p(padding)-FWidth(FilterのWidth)/S(ストライド)+1=6+2*1-2/1=7


# 最新のCNN
## Alexnet
2012年の画像認識コンペティションで大差をつけて優勝したモデル
論文も巧妙にパコピーされないようになっている
5層の畳み込み層、5層のプーリング層、3層の全結合
サイズ4096の全結合層の出力にドロップアウトを使用
その後、VGG、GoogLeNet(Google)、ResNet(MicroSoft)が登場。

## VGG(Visual Geometry Group)
Department of Engineering Science, University of Oxford
VGG-16 畳み込み13層＋全結合層３層＝16層のニューラルネットワークということで、VGG-16
https://qiita.com/MuAuan/items/86a56637a1ebf455e180

## GoogLeNet
GoogLeNet31は，2014年のILSVRCの優勝モデル。複数の畳み込み層やpooling層から構成されるInceptionモジュールと呼ばれる小さなネットワーク (micro networks) を定義し，これを通常の畳み込み層のように重ねていくことで1つの大きなCNNを作り上げている点が特徴。
https://qiita.com/yu4u/items/7e93c454c9410c4b5427

## ResNet
Residual Networks (ResNet)37は，2015年のILSVRCの優勝モデル。ネットワークを深くすることは表現能力を向上させ、認識精度を改善するが、あまりにも深いネットワークは効率的な学習が困難になる。ResNetは通常のネットワークのように何かしらの処理ブロックによる変換F(x)F(x)を単純に次の層に渡していくのではなく、その処理ブロックへの入力xxをショートカットし、H(x)=F(x)+xH(x)=F(x)+xを次の層に渡すことが行われる。このショートカットを含めた処理単位をresidualモジュールと呼ぶ。ResNetではショートカットを通してbackpropagation時に勾配が直接下層に伝わっていくことになり、非常に深いネットワークにおいても効率的に学習ができるようになった。