Optimizer 3
Prologue
勾配降下発展の方向は大きく2つある.1つ目は物理の法則に従う方法です.第2の方法は,学習回数の増加に伴い,一定の割合で学習率を減少させ,グローバル最小値を超えないようにすることである.今回知っておきたいのは、2つの方法を組み合わせて使用するアルゴリズムです.import numpy as np
import matplotlib.pyplot as plt
def f(x, y):
return 0.4*x**2*y**2 + 0.3*x**2*y + 0.3*x**2 + 0.3*y**2 - 0.25*x*y**2 + 0.31*x*y - 0.2*x + 2.1*y
def df(x, y):
dx = 0.8*x*y**2 + 0.6*y + 0.6*x - 0.5*y + 0.31*y - 0.2
dy = 0.8*x**2*y + 0.6*x**2 + 0.6*y - 0.5*x*y + 0.31*x + 2.1
return dx, dy
x = np.arange(-1, 2, 0.01)
y = np.arange(-2, 1, 0.01)
X, Y = np.meshgrid(x, f(x, y))
Z = np.sqrt(X**2 + Y**2)
plt.contour(X, Y, Z, 25, colors = ['gray'])
plt.plot(x, f(x, y))
私たちはヘメルコンボル地形です.2 D二次関数にz軸を追加し、等高線のように高さが等しい支点間を立体化します.最小の円は最小値を持つため、オプティマイザは円を低くすることができます.
Adam
MomentumとRMSPropを統合するアルゴリズム.両方のアルゴリズムが良ければ、統合したほうがいいのではないでしょうか.中には作っているIntutionが入っています混ざっているせいか複雑ですがどこに置いても良いのでよく使います.
mn=β1mn−1+(1−β1)∇f(θn), m1=0m_n =\beta_1 m_{n-1}+(1-\beta_1)\nabla f(\theta_n),\m_1 =0mn=β1mn−1+(1−β1)∇f(θn), m1=0
vn=β2vn−1+(1−β2)∇f(θn)⊙∇f(θn), v1=0v_n=\beta_2 v_{n-1}+(1-\beta_2)\nabla f(\theta_n)\odot\nabla f(\theta_n),\v_1 = 0vn=β2vn−1+(1−β2)∇f(θn)⊙∇f(θn), v1=0
このときβ1\beta_1β第1課β2\beta_2β2の初期値はそれぞれ0.99と0.999であった.α\alphaα10,310^{−3}10σ3と命名した.このように、m 1 m 1 m 1 m 1およびv 1 v 1 v 1は0であるため、第1ステップの結リンゴ値は0になる傾向があるため、vnv nvnおよびhnh nhnを以下のように修正する.
m^n=mn1−β1n+1v^n=vn1−β2n+1\hat{m}_n=\cfrac{m_n}{1-\beta_1^{n+1}}\quad\quad\quad\hat{v}_n=\cfrac{v_n}{1-\beta_2^{n+1}}m^n=1−β1n+1mnv^n=1−β2n+1vn
したがって,点の移動は従来のアルゴリズムよりも複雑である.
θn+1=θn−α1mn^⊙v^\theta_{n+1}=\theta_{n}-\alpha\cfrac{1}{\sqrt{\hat{m_n}}}\odot\hat{v}θn+1=θn−αmn^1⊙v^
少し考えてみると、勉強が進むにつれて、m^hat{m}m^とv^hat{v}v^がmmmとnnnに近づき、結局SGDに似ている.def adam(x, y, cache: dict, beta1 = 0.9, beta2 = 0.999, lr= 5e-2):
t = 0
dx, dy = df(x, y)
if len(cache['m']['x']) == 0 and len(cache['v']['y']) == 0:
mx = (1 - beta1) * dx
my = (1 - beta1) * dy
vx = (1 - beta2) * np.square(dx)
vy = (1 - beta2) * np.square(dy)
else:
mx = beta1 * cache['m']['x'][-1] + (1 - beta1) * dx
my = beta1 * cache['m']['y'][-1] + (1 - beta1) * dy
vx = beta2 * cache['v']['x'][-1] + (1 - beta2) * np.square(dx)
vy = beta2 * cache['v']['y'][-1] + (1 - beta2) * np.square(dy)
t += 1
cache['m']['x'].append(mx)
cache['m']['y'].append(my)
cache['v']['x'].append(vx)
cache['v']['y'].append(vy)
hat_mx = mx / (1 - beta1**t)
hat_my = my / (1 - beta1**t)
hat_vx = vx / (1 - beta2**t)
hat_vy = vy / (1 - beta2**t)
x = x - lr * hat_mx / (np.sqrt(hat_vx)- 1e-8)
y = y - lr * hat_my / (np.sqrt(hat_vy)- 1e-8)
return x, y
cache = {'v':{'x':[], 'y':[]}, 'm':{'x':[], 'y':[]}}
adamX, adamY = [.5], [5.8]
x, y = adam(*adamX, *adamY, cache)
adamX.append(x)
adamY.append(y)
for i in range(92):
x, y = adam(x, y, cache)
adamX.append(x)
adamY.append(y)
plt.contour(X, Y, Z, 25, colors= ['gray'])
plt.plot(adamX, adamY)
plt.title('Adam')
plt.xlabel('lr=5e-2, epochs=92')
2つの特性が混在しているためか,この課題ではSGDよりも基本設定が収束しにくく,アルゴリズムはより高い学習率を要求しているようである.
Epilogue
import numpy as np
import matplotlib.pyplot as plt
def f(x, y):
return 0.4*x**2*y**2 + 0.3*x**2*y + 0.3*x**2 + 0.3*y**2 - 0.25*x*y**2 + 0.31*x*y - 0.2*x + 2.1*y
def df(x, y):
dx = 0.8*x*y**2 + 0.6*y + 0.6*x - 0.5*y + 0.31*y - 0.2
dy = 0.8*x**2*y + 0.6*x**2 + 0.6*y - 0.5*x*y + 0.31*x + 2.1
return dx, dy
x = np.arange(-1, 2, 0.01)
y = np.arange(-2, 1, 0.01)
X, Y = np.meshgrid(x, f(x, y))
Z = np.sqrt(X**2 + Y**2)
plt.contour(X, Y, Z, 25, colors = ['gray'])
plt.plot(x, f(x, y))
MomentumとRMSPropを統合するアルゴリズム.両方のアルゴリズムが良ければ、統合したほうがいいのではないでしょうか.中には作っているIntutionが入っています混ざっているせいか複雑ですがどこに置いても良いのでよく使います.
mn=β1mn−1+(1−β1)∇f(θn), m1=0m_n =\beta_1 m_{n-1}+(1-\beta_1)\nabla f(\theta_n),\m_1 =0mn=β1mn−1+(1−β1)∇f(θn), m1=0
vn=β2vn−1+(1−β2)∇f(θn)⊙∇f(θn), v1=0v_n=\beta_2 v_{n-1}+(1-\beta_2)\nabla f(\theta_n)\odot\nabla f(\theta_n),\v_1 = 0vn=β2vn−1+(1−β2)∇f(θn)⊙∇f(θn), v1=0
このときβ1\beta_1β第1課β2\beta_2β2の初期値はそれぞれ0.99と0.999であった.α\alphaα10,310^{−3}10σ3と命名した.このように、m 1 m 1 m 1 m 1およびv 1 v 1 v 1は0であるため、第1ステップの結リンゴ値は0になる傾向があるため、vnv nvnおよびhnh nhnを以下のように修正する.
m^n=mn1−β1n+1v^n=vn1−β2n+1\hat{m}_n=\cfrac{m_n}{1-\beta_1^{n+1}}\quad\quad\quad\hat{v}_n=\cfrac{v_n}{1-\beta_2^{n+1}}m^n=1−β1n+1mnv^n=1−β2n+1vn
したがって,点の移動は従来のアルゴリズムよりも複雑である.
θn+1=θn−α1mn^⊙v^\theta_{n+1}=\theta_{n}-\alpha\cfrac{1}{\sqrt{\hat{m_n}}}\odot\hat{v}θn+1=θn−αmn^1⊙v^
少し考えてみると、勉強が進むにつれて、m^hat{m}m^とv^hat{v}v^がmmmとnnnに近づき、結局SGDに似ている.
def adam(x, y, cache: dict, beta1 = 0.9, beta2 = 0.999, lr= 5e-2):
t = 0
dx, dy = df(x, y)
if len(cache['m']['x']) == 0 and len(cache['v']['y']) == 0:
mx = (1 - beta1) * dx
my = (1 - beta1) * dy
vx = (1 - beta2) * np.square(dx)
vy = (1 - beta2) * np.square(dy)
else:
mx = beta1 * cache['m']['x'][-1] + (1 - beta1) * dx
my = beta1 * cache['m']['y'][-1] + (1 - beta1) * dy
vx = beta2 * cache['v']['x'][-1] + (1 - beta2) * np.square(dx)
vy = beta2 * cache['v']['y'][-1] + (1 - beta2) * np.square(dy)
t += 1
cache['m']['x'].append(mx)
cache['m']['y'].append(my)
cache['v']['x'].append(vx)
cache['v']['y'].append(vy)
hat_mx = mx / (1 - beta1**t)
hat_my = my / (1 - beta1**t)
hat_vx = vx / (1 - beta2**t)
hat_vy = vy / (1 - beta2**t)
x = x - lr * hat_mx / (np.sqrt(hat_vx)- 1e-8)
y = y - lr * hat_my / (np.sqrt(hat_vy)- 1e-8)
return x, y
cache = {'v':{'x':[], 'y':[]}, 'm':{'x':[], 'y':[]}}
adamX, adamY = [.5], [5.8]
x, y = adam(*adamX, *adamY, cache)
adamX.append(x)
adamY.append(y)
for i in range(92):
x, y = adam(x, y, cache)
adamX.append(x)
adamY.append(y)
plt.contour(X, Y, Z, 25, colors= ['gray'])
plt.plot(adamX, adamY)
plt.title('Adam')
plt.xlabel('lr=5e-2, epochs=92')
2つの特性が混在しているためか,この課題ではSGDよりも基本設定が収束しにくく,アルゴリズムはより高い学習率を要求しているようである.
Epilogue
Reference
この問題について(Optimizer 3), 我々は、より多くの情報をここで見つけました https://velog.io/@iissaacc/Optimizer-3テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol