绿色健康小清新

耐得住寂寞,守得住繁华

李宏毅机器学习-48-02-ML-Gradient Descent as LSTM

Meta Learning - Gradient Descent as LSTM

上次说到meta learning是在训练一个learning algorithm。使用的方法是梯度下降,这次我们研究如何将这个learning algorithm看作是一个LSTM,我们通过训练这个LSTM网络来实现我们的meta learning。

我们观察这个网络,发现很像是一个RNN,我们的training data就像我们RNN中的输入x,之后参数ϕ\phi 就像是之前RNN中的h(x),不断的更新。下面罗列的是将learning algorithm看作是RNN的论文。

👉 OPTIMIZATION AS A MODEL FOR FEW-SHOT LEARNING

👉 Learning to learn by gradient descent by gradient descent

Recurrent Neural Network

前面我们已经介绍过了RNN和LSTM了,链接如下:

👉 机器学习-13-Recurrent Neural Network part1(循环神经网络RNN part1)

👉 机器学习-14-Recurrent Neural Network part2(循环神经网络RNN part2)

这里我们仅仅简单进行一下回顾!

输入x是输入的各个序列的字符(可以理解为是吃进去的字),其二是一个h,h可以是参数,也可以是人为设定的。输出是y和h。我们要注意的是输入的h和输出的h一定要具有相同的格式的。

我们再来回顾一下LSTM和普通的RNN之间有什么不同的地方。RNN是两个输入,两个输出而LSTM是具有三个输入,三个输出。其中c是变化很小的,而h是具有很大变化的。所以很多人都会说c是可以存储很久远记忆的,而h是会有忘记的。

LSTM有三个gate:

  • 当某个neuron的输出想要被写进memory cell,它就必须要先经过一道叫做input gate的闸门,如果input gate关闭,则任何内容都无法被写入,而关闭与否、什么时候关闭,都是由神经网络自己学习到的

  • output gate决定了外界是否可以从memory cell中读取值,当output gate关闭的时候,memory里面的内容同样无法被读取

  • forget gate则决定了什么时候需要把memory cell里存放的内容忘记清空,什么时候依旧保存

我们再来回顾一下LSTM的计算流程,如果从表达式的角度看LSTM,它比较像上图中的样子:

  • zz是想要被存到cell里的输入值:将xtx^tht1h^{t-1}接在一起,之后和一个参数矩阵WW相乘,之后再加上一个tanh(hyperbolic tangent function)激活函数得到z。
  • ziz^i是操控input gate的信号:将xtx^tht1h^{t-1}接在一起,之后和一个参数矩阵WiW^i相乘
  • zoz^o是操控output gate的信号:将xtx^tht1h^{t-1}接在一起,之后和一个参数矩阵WoW^o相乘
  • zfz^f是操控forget gate的信号:将xtx^tht1h^{t-1}接在一起,之后和一个参数矩阵WfW^f相乘

我们得到z,zi,zf,z0z,z^i,z^f,z^0 后:

  • zzziz^i 做点乘

    zizz^i\odot z

  • 上步结果加上ct1c^{t-1}zfz^f 做点乘得到新的ctc^t

    ct=zfct1+zizc^t = z^f \odot c^{t-1} + z^i\odot z

  • 之后再将ctc^t 经过一个激活函数tanh,之后再和zoz^o 做点乘,得到hth^t

    ht=zotanh(ct)h^t = z^o \odot tanh(c^t)

  • 再用hth^tWW' 做乘法,再加一个激活函数,得到yty^t

    yt=σ(Wht)y^t = \sigma(W'h^t)

以上就是LSTM中一个计算单元的全部计算过程。

因为这是一个循环神经网络嘛,所以当然不会只进行一次计算。

我们刚才得到了新的参数hth^tctc^t,之后又有新的输入xt+1x^{t+1}。之后,按照上面的步骤,我们就不断的进行循环计算,得到最后的值。


Similar to gradient descent based algorithm

上面我们简单介绍了一下LSTM,那么问题来了,我们Meta Learning中的θ\theta 在LSTM中又该如何训练呢?又或者说我们如何用LSTM代替Gradient Descent求θ^\hat{\theta}

我们将LSTM的式子和我们最初的梯度下降的式子都罗列出来看看。

上面是梯度下降的式子:

θt=θt1ηθl\theta^t = \theta^{t-1}-\eta\bigtriangledown_{\theta}l

下面是LSTM的式子:

ct=zfct1+zizht=zotanh(ct)yt=σ(Wht)\begin{aligned} & c^t = z^f \odot c^{t-1} + z^i\odot z \\ & h^t = z^o \odot tanh(c^t) \\ & y^t = \sigma(W'h^t) \end{aligned}

我们发现梯度下降左边是θt\theta^t ,右边是θt1\theta^{t-1},之后LSTM的第一个式子左边是ctc^t ,右边是ct1c^{t-1}。于是我们就想,可不可以把cc当成θ\theta来看呢!其实就是将cc当成是神经网络的参数来看待。

看上图中,我们将LSTM的架构进行了简化,只保留了更新memory cell中cc的部分;然后将cc换成了θ\theta ,因此每次更新θ\theta 都会经历这一个过程(式子):

θt=zfθt1+ziz\theta^t = z^f\odot\theta^{t-1} + z^i\odot z

当然这个式子看起来和Gradient Descent的式子还有一些差异,我们进一步分析:

这里对式子

θt=zfθt1+ziz\theta^t = z^f\odot\theta^{t-1} + z^i\odot z

进行进一步的替换,将zz 替换成 θl-\bigtriangledown_{\theta}l(梯度的负数):

θt=zfθt1+ziθl\theta^t = z^f\odot\theta^{t-1} + z^i\odot -\bigtriangledown_{\theta}l

然后,将zfz^f 替换成全是11的常量矩阵,将ziz^i替换成全是η\eta的常量矩阵。

这样整个LSTM就换成是一个梯度下降的式子,每个时刻对θ\theta 的更新就可以看做是进行了一次Gradient Descent!也可以理解为梯度下降就是LSTM的特殊形式。

上面看似已经很完美了!但是我们再思考一个问题,上面式子的zfz^fziz^i 都是直接给出的,但是我们现在想能否将其动态的学习出来呢!?

这将是我们所想要解决的问题。我们前面是只假设input只有θl-\bigtriangledown_{\theta}l,但其实我们可以拿别的信息一起作为input!

比如说:我们可以将在θt1\theta^{t-1}参数下算出来的loss当做输入来controlziz^izfz^f的值

这样子,我们学出来的zfz^f 在计算θt\theta^t的时候 ,就像是在做一个回归的运算,也就是做一个weight decay,将前面算出来的θt1\theta^{t-1}乘以zfz^f来进行适当的缩小;而在计算ziz^i 的时候,更像是在动态的决定一个LR过程。

我们来看一下梯度下降版的LSTM是什么情况的。计算过程如上图所示。

  • 我们的输入是一个θ0\theta^0 。同时我们提取出一个batch的数据,之后我们将其通过参数θ\theta ,得到梯度的负数,我们将这两个作为“LSTM”的输入,之后进行训练,假设我们循环三次LSTM,得到了最终的θ^\hat{\theta} (θ3\theta^3 )。

  • 用测试数据在参数θ^\hat{\theta}下得到预测值,我们将其和真实值做比较,就得到模型的loss。

  • 这个loss就是我们要Minimize的目标!因此我们要做的就是用得到的loss通过Gradient Descent,不断的更新LSTM的参数去Minimize最终的输出loss

其实我们这个Model和LSTM还有一个区别。在LSTM中,ct1c^{t-1}xtx^t是独立的,也就是说在memory cell中存储的值不会影响当前时刻看到的输入xtx^t 。而在这个Model中,输入θl-\bigtriangledown_{\theta}l是要对θ\theta求gradient,也就是说θ\theta的值会影响接下来的输入θl-\bigtriangledown_{\theta}l,两者之间并不是独立的!

这里我们的做法是:假设θ\thetaθl-\bigtriangledown_{\theta}l的关系是不存在的!直接train就行了!

而且在这个架构下,我们可以把θ0\theta^0也当做是参数,直接学出来!


Real Implementation

在实做中,可能有人会说,我们神经网络有成千上万的参数,难道我们需要成千上万个LSTM吗?我们训练一千个LSTM就很费劲了,那么我们要怎么做呢?

我们其实就训练一个LSTM的神经元,之后所有的参数,都使用这样的LSTM来更新。

那么又有人会问,使用相同的LSTM的话,难道不会使所有的参数训练以后都相同吗?其实是不会的,因为我们参数的初始值是不相同的,所以我们训练的梯度也是不相同的,所以我们得到的参数也不相同。

我们这样做其实是有自身的道理的:

  1. 我们不可能训练成千上万个LSTM的神经元,因为过于巨大
  2. 我们以往的更新策略其实也是对于不同的参数采用相同的更新策略
  3. 我们以往使用MAML的时候我么训练的模型和测试的模型必须是相同的,但是现在我们没有这方面的顾虑了,因为我们使用相同的LSTM更新参数,无论参数个数多少都无所谓了。

Experimental Results

这个是论文中的实验结果,横轴是update的次数,纵轴是forget gate(zfz^f 值)和input gate的值(ziz^i)的值。可以看到经过学习以后,zfz^f 的值一般都是稳定在1上,而ziz^i 的值是动态变化的。

通过我们之前的学习,我们知道很多时候参数的更新不仅仅是依靠当前的梯度,很多时候是依靠一直以来的梯度加在一起所得到的结果的,比如RMSProp,Momentum。但是我们刚才并没有思考这些,所以我们现在思考能不能将过去的梯度和现在的梯度做一个整合处理。

所以我们就想多加一层LSTM,就是将梯度加入到一个绿色的LSTM层中,之后下面的LSTM层可以对之前的梯度进行整合。

最后这个是实验的数据结果,上图中,因为minist数据集的话,做meta learning 意义不大。因此train 20个unit test 40个unit 的对比,以及test 2 layer 的对比,效果都很好。但是当train 是sigmoid ,test是relu函数时,效果就差了。

其实就是反映出LSTM相较于其他的更新方法来说是十分具有优势的,同时当train和test的层数等等是不一样的时候,我们的LSTM是不同的。

-------------本文结束感谢您的阅读-------------
六经蕴籍胸中久,一剑十年磨在手

欢迎关注我的其它发布渠道