Tensorflow:关于adam优化器的困惑

时间:2016-06-15 18:17:40

标签: python tensorflow

关于adam优化器如何在tensorflow中实际工作,我感到很困惑。

我阅读docs的方式,它表示每个梯度下降迭代都会改变学习速率。

但是当我调用该函数时,我会给它一个学习率。我并没有把这个函数称为,做一个时代(隐式地调用#iterations以便进行我的数据训练)。我明确地将每个批次的函数称为

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

所以我的eta无法改变。而且我没有传入时间变量。或者这是某种生成器类型的东西,每当我调用优化器时,会话创建t会增加吗?

假设它是一些生成器类型的东西并且学习率正在无形地降低:我如何在不降低学习速率的情况下运行adam优化器?在我看来,RMSProp基本上是相同的,我唯一需要做的就是让它等于(学习率忽略不计)是将超参数momentumdecay更改为分别匹配beta1beta2。这是对的吗?

2 个答案:

答案 0 :(得分:22)

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

您的参数

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

    一般来说,epsilon的默认值1e-8可能不是一个好的默认值。例如,在ImageNet上训练Inception网络时,当前的好选择是1.0或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将跟踪渐变的移动平均值及其平方。 (因此,如果您有1M个参数,Adam将在内存中保留2M个参数)

在每次迭代t以及模型的每个参数

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

答案 1 :(得分:2)

RMS_PROP和ADAM都具有自适应学习速率。

基本RMS_PROP

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

你最初可以看到这有两个参数 decay_rate&amp; 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是最近提出的更新,看起来有点像RMSProp   动量

是的!然后是什么使rms_prop与动量有所不同?

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