Tensorflow:关于adam optimiz的困惑

2024-04-28 09:24:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我对adam优化器在tensorflow中的实际工作方式感到困惑。

我阅读docs的方式是,学习率在每次梯度下降迭代中都会改变。

但是当我调用这个函数时,我给它一个学习速率。我不会调用函数,比如说,执行一个epoch(隐式调用迭代,以便通过我的数据训练)。我为每个批显式调用函数,如下所示

for epoch in epochs
     for batch in data
          sess.run(train_adam_step, feed_dict={eta:1e-3})

所以我的预计到达时间不能改变。我不会把时间变量传进来。或者这是某种生成器类型的东西,在会话创建时,每次调用优化器时t都会递增?

假设这是某种生成器类型的事情,并且学习率正在无形中降低:我如何才能在不降低学习率的情况下运行adam优化器?在我看来RMSProp基本上是一样的,我要做的唯一的事情就是改变超参数momentumdecay来分别匹配beta1beta2。是这样吗?


Tags: 数据函数indocs类型for速率tensorflow
2条回答

我发现文档很清楚,我将在这里粘贴伪代码算法:

您的参数:

  • learning_rate:在1e-4和1e-2之间是标准的
  • beta1:默认为0.9
  • beta2:默认为0.999
  • epsilon:默认为1e-08

    The default value of 1e-8 for epsilon might not be a good default in general. For example, when training an Inception network on ImageNet a current good choice is 1.0 or 0.1.


初始化:

m_0 <- 0 (Initialize initial 1st moment vector)
v_0 <- 0 (Initialize initial 2nd moment vector)
t <- 0 (Initialize timestep)

m_tv_t将跟踪每个网络参数的梯度及其平方的移动平均值。(因此,如果有1个参数,Adam将在内存中多保留2个参数)


在每次迭代时{},对于模型的每个参数:

t <- t + 1
lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t)

m_t <- beta1 * m_{t-1} + (1 - beta1) * gradient
v_t <- beta2 * v_{t-1} + (1 - beta2) * gradient ** 2
variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)

这里lr_tlearning_rate有点不同,因为对于早期的迭代,移动平均值还没有收敛,所以我们必须通过乘以sqrt(1 - beta2^t) / (1 - beta1^t)来规范化。当t高(t > 1./(1.-beta2))时,lr_t几乎等于learning_rate


要回答你的问题,你只需要通过一个固定的学习率,保持beta1beta2的默认值,也许修改epsilon,Adam就会变魔术:)


链接RMSProp

beta1=1的Adam等价于带momentum=0的RMSProp。Adam的参数beta2和RMSProp的参数decay是相同的。

然而,RMSProp并没有保持梯度的移动平均值。但它可以保持势头,就像MomentumOptimizer一样。

rmsprop的详细说明。

  • 保持梯度平方的移动(贴现)平均值
  • 用这个平均值的根除以梯度
  • (可以保持势头)

下面是伪代码:

v_t <- decay * v_{t-1} + (1-decay) * gradient ** 2
mom = momentum * mom{t-1} + learning_rate * gradient / sqrt(v_t + epsilon)
variable <- variable - mom

RMSúPROP和ADAM都有自适应学习率。

基本RMS属性

cache = decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

您可以看到,它最初有两个参数衰减率和每股收益

然后我们可以增加一个动量,使梯度更稳定,然后我们可以写

cache = decay_rate * cache + (1 - decay_rate) * dx**2
**m = beta1*m + (1-beta1)*dx**  [beta1 =momentum parameter in the doc ]
x += - learning_rate * dx / (np.sqrt(cache) + eps)

现在你可以看到,如果我们保持beta1=o,那么它是没有动量的rms_prop。

然后是ADAM的基础知识

cs-231 Andrej Karpathy中,亚当最初是这样描述的

Adam is a recently proposed update that looks a bit like RMSProp with momentum

是的!那么,这与带有动量的rms_道具有什么区别呢?

m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
**x += - learning_rate * m / (np.sqrt(v) + eps)**

他在更新方程中再次提到,m,v更光滑。

因此,与rms_prop的不同之处在于更新的噪音更小。

什么声音?

在初始化过程中,我们将m和v初始化为零。

m=v=0

为了减少这种初始化效果,总是要进行一些预热。所以等式是

m = beta1*m + (1-beta1)*dx          beta1 -o.9 beta2-0.999
**mt = m / (1-beta1**t)**
v = beta2*v + (1-beta2)*(dx**2)
**vt = v / (1-beta2**t)**
x += - learning_rate * mt / (np.sqrt(vt) + eps)

现在我们运行这个程序几次迭代。很明显注意粗体的线条,你可以看到当t增加(迭代次数)时,mt发生的事情

mt=m

相关问题 更多 >