「Deep Learning」って何? 学習、パラメータの更新の最適化。
Deep Learningで大事なところです。学習してパラメータを最適化していくという過程を考えてみましょう。(第6章となります。)
何が大切か?ということからです。
ネットワークの中でのパラメータ更新の役割ですが、すごく重要です。これができないと正確な判定、判断できません!
これを使いやすく、わかりやすくするためにSGD(確率的勾配降下法)をクラス化します。
class SGD:
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]
paramsとgradsです。パラメータと勾配の更新をします。
実際には動かない単純なモデル(イメージ)で本の中で説明されていますのでそのまま引用します。
ネットワーク2層のネットワークを使います。
network = TwoLayerNet(...)
そして先ほど作ったクラス
optimizer = SGD()
ネットワーク、最適化するクラスを実装して実際に使う想定でコードを組むと、
for i in range(10000) :
...
x_bath, t_bath = get_mini_batch(...)
grads = network.gradient(x_batch, t_batch)
params = network.params
optimizer.update(params, grads)
...
こんな感じで"optimizer"を実行することでネットワークのパラメータ、勾配を最適化します。
例示しているSGDには欠陥(更新経路についてジグザグ)があるために他の方法も考えられていて、ネットワークごとに判断されているところです。
Momentum
更新経路についてSGDがジグザグなのに対して少し軽減することができる。
class Momentum:
"""Momentum SGD"""
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():
self.v[key] = self.momentum*self.v[key] - self.lr*grads[key]
params[key] += self.v[key]
AdaGrad
最小値に向かって効率的に動くことができる。
class AdaGrad:
"""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():
self.h[key] = np.zeros_like(val)
for key in params.keys():
self.h[key] += grads[key] * grads[key]
params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
Adam
MomentumとAdaGradとの融合
class Adam:
"""Adam (http://arxiv.org/abs/1412.6980v8)"""
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():
#self.m[key] = self.beta1*self.m[key] + (1-self.beta1)*grads[key]
#self.v[key] = self.beta2*self.v[key] + (1-self.beta2)*(grads[key]**2)
self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
self.v[key] += (1 - self.beta2) * (grads[key]**2 - self.v[key])
params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)
#unbias_m += (1 - self.beta1) * (grads[key] - self.m[key]) # correct bias
#unbisa_b += (1 - self.beta2) * (grads[key]*grads[key] - self.v[key]) # correct bias
#params[key] += self.lr * unbias_m / (np.sqrt(unbisa_b) + 1e-7)
いろいろ試してみたいと思います。まずはイメージから。最適化のイメージは少し持てたかな?少しずつやっていきましょ。
この記事が気に入ったらサポートをしてみませんか?