【NLP】第四章:门控循环单元GRU

embedded/2024/12/4 4:03:07/

四、门控循环单元GRU

建议看本篇时,一定一定要把前面的LSTM先看看:【NLP】第三章:长短期记忆网络LSTM-CSDN博客 ,当你对LSTM的各个方面的细节都清晰了,GRU就是闭眼就会的,就是秒懂的,而且以后你再听到什么就不再迷惑了。也正是因为LSTM我写的太详细了,所以本篇的GRU我就简单说一下重点就过了。

门控循环单元Gated Recurrent Unit,GRU,是在LSTM基础上改进的,所以它也是LSTM的一个变体。 GRU是在2014年Cho,etal.《Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling》(门控循环神经网络在序列建模上的实证评估)论文中提出的,是目前非常流行的一个变体,因为它比LSTM网络要简单,但在某些情况能产生同样出色的效果,所以非常受欢迎。

1、GRU原理及架构

上图是GRU的计算过程。我在网上看很多解读GRU的文章,感觉非常凌乱,一个人一个说法。而且上面左图的数据流图让人看了也很懵(当然当你懂的时候你不会懵,但当你是一个新手,第一时间看到它还是感觉很懵的),所以建议也不要看左图,直接理解右图的公式就行。   

按照LSTM的分析逻辑,我这里总结下面几点:
(1)上图就是GRU网络的一个重复模块。有的资料叫节点,有的叫单元,有的叫循环单元,,,等等各种叫法,所以我们也不用纠结。这里我叫重复模块也是我自己沿用LSTM中的叫法。所以GRU也是和RNN、LSTM一样,都是重复模块在时序维度上的串联结构。

(2)GRU模块的输入只有ht-1和xt。ht-1就可以理解为记忆信息。xt就是时序样本了。

(3)GRU模块的输出只有ht,也就是记忆信息了。

GRU的输入输出都比LSTM简单,LSTM还有一个Ct,就是所谓的长期记忆。而GRU没有分所谓的长期信息、短期信息,只有一条ht,叫隐藏信息

(4)GRU模块只有两个门结构。一个叫重置门(reset gate),一个叫更新门(update gate)。
我个人认为真是没必要纠结这两个门的名称,甚至不用纠结他们的功能有啥区别。因为你单单从名称上看,重置和更新这两个词有啥区别?!似乎没有吧。而看网上很多资料也是解读的五花八门。比如重置门,有人说"用于控制之前的记忆需要保留多少"。而别的人又说"重置门主要决定了到底有多少过去的信息需要遗忘"。哎,笑一会儿,本来记忆和遗忘就是一体两面,非此即彼的。所以一个人一种话术,一篇博客一种理解。所以我就说,我们就不要纠结名称,也不要纠结功能了。

从上图的公式看,其实这两个门,仅仅是两个门而已,它们两个的计算一模一样,输入一模一样,只是使用了两个不同的矩阵线性变换了一下,而且这两个矩阵都是随机生成的,只有在训练过程中,这两个门才会慢慢迭代成其功能的门。所以现在这两个门,从架构上看只是两个全连接线性层而已,从数学的角度看只是两个系数矩阵而已

(5)GRU的原理是:学一个重置门rt,让rt先过滤一遍输入的记忆信息ht-1,然后把过滤后的记忆信息和本时间步样本数据一起,用一个线性层+tanh学习一下,变成新的记忆信息ht漂。
然后再学习一个更新门zt,如果说zt是要记住的系数,那1-zt就是要遗忘的系数。
一是,用1-zt乘以更新前的ht-1,就表示该忘记的就彻底忘记了吧,就是又加强了一次忘记。
二是,用zt乘以ht漂,就表示该记住的就一定要记牢,就是又加强了一次记忆。
最后,把"该忘记的就干脆彻底的忘记、该牢记的就是加强记忆"的记忆信息ht输出即可。

(如果说zt是要遗忘的系数,那1-zt就是要记住的系数。
1-zt乘以更新前的ht-1,就表示该记住的就一定要记牢,就是又加强了一次记忆。
zt乘以ht漂,就表示该忘记的就彻底忘记了吧,就是又加强了一次忘记。
最后也是把"该忘记的就干脆彻底的忘记、该牢记的就是加强记忆"的记忆信息ht输出即可。)

2、pytorch中实现GRU的数据流
GRU的原理基本上就是这样的。我们下面看看pytorch中实现GRU的数据流,来印证我们上面说的原理。
在pytorch.nn下面也有GRU类torch.nn.GRU。我们看看pytorch是如何实现GRU的,也就是从代码角度看看它的数据流:

上图我手动计算出来的结果和pytorch计算出来的结果一模一样。说明我们理解的原理没错。但是这里想说的是,这里其实有两个坑,害我找了好半天:

左边的公式是我们讲原理时用的公式,但是pytorch使用的公式是右边截图中的公式。两边还是有一些差异的,不知道是pytorch开发人员的失误还是理解错误,A处的公式到B处,它就给ht-1和ht漂换了个位置。这也就是为什么我一开始就强调不要去纠结是遗忘还是忘记,因为遗忘就等于1-记住,记住=1-遗忘,所以就别区分到底是忘记了还是记住了。

第二个坑就是上图的C处,我一开始先计算的rt*ht-1,然后再进行线性变换,一看结果对不上,查看GRU的说明文档才发现,pytorch老人家是先线性变换后再乘rt的。

这算是踩的两个坑吧。从这两个坑也可以看出,其实没有特别肯定的做法,每个人都是按照自己的理解去做的。

最后说一嘴,网上很多资料还经常提到GRU是如何避免梯度消失的?如果说lstm是因为并联三条线路来避免梯度消失,那GRU就是利用遗忘=1-记忆,或者说记忆=1-遗忘,这个巧妙地设计来避免梯度消失的。

个人感觉没有其他要深究的了,知道它的数据流,会用,知道可能出现的问题症结在哪里就可以了,其他就没有什么要探索了。本篇是最简单最短的一篇文章了,因为所有的细节在LSTM中都详细解释过了,没必要一遍遍的重复了。

最后总结一个LSTM和GRU的终极版数据流:
(1)LSTM

(2)GRU

至此可以说RNN一族的架构就算是讲解完毕了。

以后再遇到有谁说RNN循环网络,指的就是我们这三章里面讲的Simple RNN-> LSTM-> GRU这三个算法,当然它们都还有stacked就是深度deep rnn->deep lstm->deep gru,以及双向的bi-rnn->bi-lstm->bi-gru,这些都是循环网络RNN一族的算法。

后面开讲处理序列数据的另外一族算法——Transformer一族,是目前NLP领域中占据着统治地位的一族算法。           


http://www.ppmy.cn/embedded/142795.html

相关文章

.net core 创建linux服务,并实现服务的自我更新

目录 创建服务创建另一个服务,用于执行更新操作给你的用户配置一些systemctl命令权限 创建服务 /etc/systemd/system下新建服务配置文件:yourapp.service,内容如下: [Unit] Descriptionyourapp Afternetwork.target[Service] Ty…

架构03-事务处理

零、文章目录 架构03-事务处理 1、本地事务实现原子性和持久性 (1)事务类型 **本地事务:**单个服务、单个数据源**全局事务:**单个服务、多个数据源**共享事务:**多个服务、单个数据源**分布式事务:**多…

C语言第十四周课——课堂练习

目录 1.冒泡法排序(降序排列) 2.控制台输出100以内的素数 3. 计算1-100的和 1.冒泡法排序(降序排列) 要求使用for循环,并且写死数据 写死数据:不从控制台输入,在排序前定义好需要排序的数据 …

【算法刷题指南】优先级队列

🌈个人主页: 南桥几晴秋 🌈C专栏: 南桥谈C 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据…

【linux】(21)进程端口排查-fuser

fuser 是一个用于显示进程使用的文件、套接字或端口的 Linux 命令。它可以帮助诊断某个文件、目录、端口或设备被哪个进程占用。 基本语法 fuser [选项] 文件或端口常用选项 选项说明-a显示所有指定文件或端口的进程信息。-k杀死占用指定文件或端口的进程。-i在杀死进程前询问…

在线家具商城基于 SpringBoot:设计模式与实现方法探究

第3章 系统分析 用户的需求以及与本系统相似的在市场上存在的其它系统可以作为系统分析中参考的资料,分析人员可以根据这些信息确定出本系统具备的功能,分析出本系统具备的性能等内容。 3.1可行性分析 尽管系统是根据用户的要求进行制作,但是…

LearnOpenGL学习(光照 -- 投光物,多光源)

完整代码见:zaizai77/Cherno-OpenGL: OpenGL 小白学习之路 投光物 将光投射(Cast)到物体的光源叫做投光物(Light Caster) 平行光 当我们使用一个假设光源处于无限远处的模型时,它就被称为定向光,因为它的所有光线都有着相同的方向&#x…

mysql order by后进行limit分页查询出现重复数据

1、场景:管理台列表查询莫名出现重复数据,第一页的最后几条数据在第二页的最上面也出现了。 select c.* from (select a.* from a where xxx union select b.* from b where xxx ) c where xxx order by c.acct_date desc limit pageSize,pageNum 2、排…