GRU 改变了RNN 的隐藏层,使其可以更好的捕捉深层连接,并改善了梯度消失问题。 GRU可以更好的捕捉非常长范围的依赖,让RNN更加有效。
-
RNN
下图为 RNN 隐藏层单元的可视化呈现,我们将使用相似的图来讲解 GRU 。
-
GRU
下图左上角的小图可以更好的解释GRU。
给定一个句子,如下图所示。当我们从左向右读这个句子的时候,GRU 单元将会有个新的变量 C ,代表细胞,即记忆细胞。记忆细胞的作用是提供了记忆的能力,比如说,对于一只猫是单数还是复数,当他看到之后的句子时仍能够判断句子的主语是单数还是复数。于是在时间 t 处记忆细胞有关于 t 的值 C<t>,GRU实际上是输出了 a<t> 的激活值,于是我们想要使用不同的符号 c 和 a 来表示记忆细胞的值和输出的激活值,即使他们是一样的,但当之后谈到 LSTM 的时候这两个代表两个不同的值。 在每个时间步,我们将用一个候选重写记忆细胞 即C~<t>,表达式如下,所以候选值替代了 C<t> 的值。
GRU 真正的思想是 有个门 用希腊字母表示,下标 u 代表更新门,这是一个 0 - 1 之间的值。可以理解为将 C~<t> 扔到 Sigmod 激活函数中,因为Sigmod 函数的输出值总是在 0 - 1 之间。
整个GRU 的关键部分就是 用 C~ 更新 c 的等式,然后门决定是否真的要更新它。于是对于上图中的句子( The cat, which already ate ... , was fulll.) 我们这样看待它,记忆细胞将会被设定为 0 或 1 这取决于你考虑的单词在句子中是单数还是复数,因为 cat 是单数的情况,所以我们先假定将它设置为1,然后 GRU 会一直记住 C<t> 的值,直到遇到 was 之前一直是 1,然后告诉它 这里是单数,所以用 was。 于是门的作用是决定什么时候会更新这个值。特别是当看到句子的主语 the cat 时,你知道在说一个新的概念,这是一个好的时机去更新这个 bit ,然后当你使用它的时候,猫……..吃饱了 就知道 我不需要记住他了,我可以忘了它了。
所以接下来要给 GRU 的式子(上图中最下面式子)。可以看到,当更新值(门)= 1 时,把这个新值 即 C<t> 设置为候选值,门值设置为 1,然后再往后更新这个值。对于中间的所有值,应该把门值设定为 0,意思就是说不更新它,就用旧的值,期间也不要遗忘掉这个值。直到遇到 was 之前始终 C<t> = C<t-1>,于是它仍然记得猫是单数的。