神经网络优化器

2023-08-25 12:04:15 浏览数 (1)

神经网络参数优化器

  • 待优化参数w
  • 损失函数loss
  • 学习率lr
  • 每次迭代一个batch
  • t表示当前迭代的总次数

关注量

下面是我们t时刻需要关注的量:

  1. 如何计算t时刻损失函数关于当前参数的梯度g_t=nabla loss=frac {alpha loss}{alpha w_t}
  2. 如何计算t时刻一阶动量m_t和二阶动量V_t
  • 一阶:和梯度相关
  • 二阶:和梯度的平方相关
  1. 如何计算t时刻下降的梯度
eta_{t}=lr * m_t/ sqrt{V_{t}}
  1. 如何计算t 1时刻的参数
w_{t 1} = w_{t} - eta_{t}=w_t - lr * m_t/ sqrt{V_{t}}

SGD

常用的梯度下降方法。此时满足:

m_t=g_t;V_t=1

梯度满足:

eta_{t}=lr * m_t/ sqrt{V_{t}}=lr*g_t

t 1时刻的参数满足:

w_{t 1} = w_{t} - eta_{t}=w_t - lr * g_t

单层网络的更新参数代码:

代码语言:javascript复制
w1.assign_sub(lr * grads[0])
b1.assign_sub(lr * grads[1])

SGDM

在SGD的基础上增加一阶动量。

m_t=beta * m_{t-1} (1-beta)*g_{t}
V_t = 1

其中beta是个超参数,接近1,经验值是0.9

eta_{t}=lr * m_t/ sqrt{V_{t}}=lr*(beta * m_{t-1} (1-beta)*g_{t})

t 1时刻的参数满足:

w_{t 1} = w_{t} - eta_{t}=w_t - lr * (beta * m_{t-1} (1-beta)*g_{t})

python代码实现的过程:

代码语言:javascript复制
m_w, m_b = 0,0  # 设置两个初始值
beta = 0.9  # 超参数

m_w = beta * m_w   (1-beta) * grads[0]
m_b = beta * m_b   (1-beta) * grads[1]

w1.assign_sub(lr * m_w)
b1.assign_sub(lr * m_b)

Adagrad

在SGD的基础上增加了二阶动量

m_t=g_t;V_t=sum t_{i=1}{g_i}2

梯度满足:

eta_{t}=lr * m_t/ sqrt{V_{t}}=lr*g_t / (sum t_{i=1}{g_i}2)

t 1时刻的参数满足:

w_{t 1} = w_{t} - eta_{t}=w_t - lr * g_t / (sum t_{i=1}{g_i}2)

python实现单层网络的更新参数代码:

代码语言:javascript复制
v_w, v_b = 0, 0
v_w  = tf.square(grads[0])
v_b  = tf.square(grads[1])

w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))

RMSProp

在SGM的基础上增加二阶动量

m_t=g_t
V_t=beta V_{t-1} (1-beta)*g_t^2

梯度满足:

eta_{t}=lr * m_t/ sqrt{V_{t}}=lr*g_t / sqrt{beta V_{t-1} (1-beta)*g_t^2}

t 1时刻的参数满足:

w_{t 1} = w_{t} - eta_{t}=w_t - lr * g_t / sqrt{beta V_{t-1} (1-beta)*g_t^2}

python实现单层网络的更新参数代码:

代码语言:javascript复制
v_w, v_b = 0, 0
beta = 0.9

v_w = beta * v_w   (1 - beta) * tf.square(grads[0])
v_b = beta * v_b   (1 - beta) * tf.square(grads[1])

w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))

Adam

同时结合SGDM一阶动量和RMSProp的二阶动量

m_t=beta * m_{t-1} (1-beta)*g_{t}

修正一阶动量的偏差:

hat{m_t} = frac{m_t}{1 - beta_1^t}
V_t = beta_2*V_{t-1} (1-beta_2)*g_t^2

修正二阶动量的偏差:

hat{V_t} = frac{V_t}{1 - beta_2^t}

那么最终更新的参数为:

梯度满足:

eta_{t}=lr * hat m_t/ sqrt{hat V_{t}}=lr*frac{m_t}{1 - beta_1^t} / sqrt {frac{V_t}{1 - beta_2^t}}

t 1时刻的参数满足:

w_{t 1} = w_{t} - eta_{t}=w_t - lr*frac{m_t}{1 - beta_1^t} / sqrt {frac{V_t}{1 - beta_2^t}}

0 人点赞