💨
Deep Learning資格試験 深層学習 最適化アルゴリズム
はじめに
日本ディープラーニング協会の Deep Learning 資格試験(E 資格)の受験に向けて、調べた内容をまとめていきます。
勾配降下法
特徴
-
目的関数が最小となるパラメータを勾配表によって探す。
-
目的関数が各パラメータによって微分できる必要がある。
-
メリット
- データが冗⻑な場合の計算コストの軽減
- 望まない局所極小解に収束するリスクの軽減
- オンライン学習ができる
計算式
学習率:
確率的勾配降下法(SDG)
- 無作為に選び出されたデータを用いて行う勾配降下法である。
コード
lr 学習率(learning rate)(小数)
params 学習するパラメータ(行列)
grads パラメータの勾配(行列)
python
class SGD:
"""確率的勾配降下法(Stochastic Gradient Descent)"""
def __init__(self, lr=0.01):
# 学習率
self.lr = lr
def update(self, params, grads):
for key in params.keys():
params[key] -= self.lr * grads[key]
ミニバッチ勾配降下法
- 無作為に選び出された複数のデータを用いて行う勾配降下法である。
モメンタム
特徴
-
誤差をパラメータで微分したものと学習率の積を減算した後、現在の重みに前回の重みを減算した値と慣性の積を加算する
-
メリット
- 局所的最適解にはならず、大域的最適解となる。
- 谷間についてから最も低い位置(最適値)にいくまでの時間が早い。
計算式
学習率:
慣性:
コード
lr 学習率(learning rate)(小数)
params 学習するパラメータ(行列)
grads パラメータの勾配(行列)
momentum 慣性項の強さを決める係数(0~1)
v 前回の重み
python
class Momentum:
def __init__(self, lr=0.01, momentum=0.9):
self.lr = lr
self.momentum = momentum
self.v = None
def update(self, params, grads):
# 初回の初期値設定
if self.v is None:
self.v = {}
for key, val in params.items():
self.v[key] = np.zeros_like(val)
for key in params.keys():
# 式(1)の処理
self.v[key] = self.momentum*self.v[key] - self.lr*grads[key]
# 式(2)の処理
params[key] += self.v[key]
AdaGrad
特徴
-
誤差をパラメータで微分したものと再定義した学習率の積を減算する。
-
メリット
- 勾配の緩やかな斜面に対して、最適値に近づける。
-
デメリット
- 学習率が徐々に小さくなるので、鞍点問題を引き起こす(局所最適解から抜け出せない)事があった。
計算式
任意な値:
コード
lr 学習率(learning rate)(小数)
params 学習するパラメータ(行列)
grads パラメータの勾配(行列)
h 学習のたびに勾配の2乗ずつ増加するパラメータ毎の値(行列)
python
class AdaGrad:
def __init__(self, lr=0.01):
self.lr = lr
self.h = None
def update(self, params, grads):
# 初回の初期値設定
if self.h is None:
self.h = {}
for key, val in params.items():
# 式(3)の処理
self.h[key] = np.zeros_like(val)
for key in params.keys():
# 式(4)の処理
self.h[key] += grads[key] * grads[key]
# 式(5)の処理
params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
RMSrop
特徴
-
誤差をパラメータで微分したものと再定義した学習率の積を減算する。
-
AdaGrad よりも最近の勾配ほど強く影響する。
-
メリット
- 局所的最適解にはならず、大域的最適解となる。
- ハイパーパラメータの調整が必要な場合が少ない
計算式
0 ~ 1 の値で昔の勾配情報をどの程度使うか:
コード
lr 学習率(learning rate)(小数)
decay_rate 0 ~ 1 の値で昔の勾配情報をどの程度使うか
params 学習するパラメータ(行列)
grads パラメータの勾配(行列)
h 学習のたびに勾配の2乗ずつ増加するパラメータ毎の値(行列)
pthon
class RMSprop:
def __init__(self, lr=0.01, decay_rate = 0.99):
self.lr = lr
self.decay_rate = decay_rate
self.h = None
def update(self, params, grads):
if self.h is None:
self.h = {}
for key, val in params.items():
self.h[key] = np.zeros_like(val)
for key in params.keys():
# 式(6)の処理
self.h[key] *= self.decay_rate
self.h[key] += (1 - self.decay_rate) * grads[key] * grads[key]
# 式(7)の処理
params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
Adam
特徴
-
モメンタムの、過去の勾配の指数関数的減衰平均
-
RMSProp の、過去の勾配の 2 乗の指数関数的減衰平均
上記をそれぞれ孕んだ最適化アルゴリズムである。 -
メリット
- モメンタムおよび RMSProp のメリットを孕んだアルゴリズムである。
計算式
コード
python
class Adam:
def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):
self.lr = lr
self.beta1 = beta1
self.beta2 = beta2
self.iter = 0
self.m = None
self.v = None
def update(self, params, grads):
if self.m is None:
self.m, self.v = {}, {}
for key, val in params.items():
self.m[key] = np.zeros_like(val)
self.v[key] = np.zeros_like(val)
self.iter += 1
lr_t = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter)
for key in params.keys():
# 式(8)の処理 (モメンタム)
self.m[key] = self.beta1*self.m[key] + (1-self.beta1)*grads[key]
unbias_m += (1 - self.beta1) * (grads[key] - self.m[key])
# 式(9)の処理 (RMSrop)
self.v[key] = self.beta2*self.v[key] + (1-self.beta2)*(grads[key]**2)
unbisa_b += (1 - self.beta2) * (grads[key]*grads[key] - self.v[key])
# 式(10)の処理
params[key] -= self.lr * unbias_m / (np.sqrt(unbisa_b) + 1e-7)
参考
【決定版】スーパーわかりやすい最適化アルゴリズム -損失関数から Adam とニュートン法-
[AI 入門] ディープラーニングの仕組み ~その 4:最適化アルゴリズムを比較してみた~
ソースコードはゼロから作る Deep Learningから引用
Discussion